FUSE Health Onboarding API
The Onboarding API from FUSE Health — 5 operation(s) for onboarding.
Operations 5
POST
/api/v1/onboarding/confirm-signature-declaration
Confirm the electronic-signature declaration
#
The Onboarding API from FUSE Health — 5 operation(s) for onboarding.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/fusehealth-com:fusehealth-com-onboarding-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: FUSE Brand API (External) Onboarding API
version: 1.0.0
description: 'Server-to-server API exposing the FUSE brand-admin surface so a single brand/tenant can build its own admin frontend. Every request is authenticated with an API key bound to exactly one clinic; all data is auto-scoped to that clinic and cannot reach another brand''s data. Isolation is enforced by application-layer clinic filtering on every query.
COVERAGE: 218 operations across 180 paths, and EVERY ONE is available to every brand. There is no per-clinic enablement step. What governs access: your API key and its scopes, the clinic the key belongs to (every read and write is filtered to it), your plan''s entitlements for the two commercially-gated areas — Affiliates (`AFFILIATES_TIER_REQUIRED`) and CRM Connect (`CRM_TIER_REQUIRED`) — and rate limits.
AUTH: the external /api/v1 surface uses an API key (`x-api-key`, ApiKeyAuth). Key management (/api-keys) and /auth/signin live at the API root and use a brand-admin JWT (BearerAuth); /auth/signin itself is unauthenticated.
SCOPES: every key carries scopes; read-only is the default and mutating endpoints require the `write` scope (403 INSUFFICIENT_SCOPE otherwise). Keys default to a 1-year expiry.
RATE LIMITING: every endpoint may additionally return `429 Too Many Requests` with a `Retry-After` header; 429 is not repeated on each operation below.
PLATFORM FIELDS: product cost, fees, pharmacy routing, doctor questions and FUSE approvals are set by FUSE, not by the brand. Any write (POST/PUT/PATCH/DELETE) whose JSON body carries one of those fields at any depth — for example `pharmacyPrice`, `shippingFeeUsd`, `coolerFeeUsd`, `pharmacyId`, `preferredPharmacyId`, `pharmacyProvider`, `requiredDoctorQuestions`, `facilitationFee`, `placeholderPrice`, `legalBusinessName`, `isTemplate` or `tenantManagerApproved` — is refused with `403 PLATFORM_FIELD`, whose `fields` array lists the offending paths; remove them and resend. (One exception: `POST /api/v1/products` still accepts the `pharmacyPrice` its schema requires, and ignores it.) 403 PLATFORM_FIELD is not repeated on each operation below.'
servers:
- url: https://api-dev.fusehealth.com
description: Development
- url: https://api.fusehealth.com
description: Production
security:
- ApiKeyAuth: []
tags:
- name: Onboarding
paths:
/api/v1/onboarding/status:
get:
tags:
- Onboarding
summary: Onboarding status for the key's clinic
operationId: getApiV1OnboardingStatus
description: Full onboarding status for the clinic's brand owner.
security:
- ApiKeyAuth: []
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/v1/onboarding/request-name-change:
post:
tags:
- Onboarding
summary: One-time brand-owner name change
operationId: postApiV1OnboardingRequestNameChange
description: One-time name change before identity verification. Write-scoped.
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- firstName
- lastName
properties:
firstName:
type: string
lastName:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/v1/onboarding/confirm-signature-declaration:
post:
tags:
- Onboarding
summary: Confirm the electronic-signature declaration
operationId: postApiV1OnboardingConfirmSignatureDeclaration
description: Records the brand owner's typed-name signature declaration and advances onboarding. Write-scoped.
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- typedName
properties:
typedName:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/v1/onboarding/save-business-details:
post:
tags:
- Onboarding
summary: Save brand business details
operationId: postApiV1OnboardingSaveBusinessDetails
description: Saves the brand owner's business details (EIN, address, entity type, legal name). Write-scoped.
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
ein:
type: string
stateOfRegistration:
type: string
address:
type: string
city:
type: string
state:
type: string
zipCode:
type: string
phoneNumber:
type: string
businessType:
type: string
companyName:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/api/v1/build-readiness:
get:
tags:
- Onboarding
summary: What this brand still needs before it can sell
operationId: getApiV1BuildReadiness
description: 'A checklist computed from the brand''s real state: its programs (each one''s publish readiness, from the same readiness check the brand portal shows), storefront pages and menus, checkout, coupons, webhooks, and either going live (a Developer Sandbox key) or account activation (a live key). Each item has a status and, when something can fix it, `fixWith`: the AI connector tool to call, or where in the brand portal it is done and whether that is possible now or after going live. `readyToSell` is true for a live brand that can take checkouts and has a published program patients can check out, and for a sandbox that has such a program and a completed test checkout. `complete` adds what patients meet after buying (the `patient_portal` section): logo, reply-to email, a verified custom domain when one is set, the support AI and its help docs, and each program''s after-purchase care. `nextBest` holds the three most useful items to do next. Read-only; counts and ids only, never a patient record. Used by the FUSE AI connector''s fuse_build_checklist.'
security:
- ApiKeyAuth: []
parameters:
- name: section
in: query
required: false
description: Return only this section. readyToSell and complete always reflect the whole brand; summary and nextBest cover the returned section.
schema:
type: string
enum:
- brand
- programs
- storefront
- checkout
- coupons
- webhooks
- patient_portal
- go_live
- activation
- account
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
$ref: '#/components/schemas/BuildChecklist'
'400':
description: INVALID_SECTION — section is not one of the listed values.
'401':
$ref: '#/components/responses/Unauthorized'
components:
schemas:
BuildChecklist:
type: object
properties:
mode:
type: string
enum:
- sandbox
- live
readyToSell:
type: boolean
complete:
type: boolean
description: readyToSell, and every required patient-portal item is done (logo, reply-to email, a verified custom domain when one is set, support AI on with a published help doc, and each program's after-purchase care set up).
summary:
type: object
properties:
done:
type: integer
todo:
type: integer
blocked:
type: integer
optional:
type: integer
portal:
type: integer
waitingOnFuse:
type: integer
sections:
type: array
items:
type: object
properties:
id:
type: string
label:
type: string
items:
type: array
items:
$ref: '#/components/schemas/BuildChecklistItem'
nextBest:
type: array
items:
$ref: '#/components/schemas/BuildChecklistItem'
BuildChecklistItem:
type: object
required:
- id
- status
- headline
properties:
id:
type: string
description: Stable item id, e.g. `programs.at_least_one` or `program.<programId>.ready`.
status:
type: string
enum:
- done
- todo
- blocked
- optional
- portal
- waiting_on_fuse
- not_applicable
headline:
type: string
detail:
type: string
fixWith:
type: object
description: Either `{ tool, args?, when? }` (an AI connector tool; `when` is `after_go_live` when the tool works only once the brand is live) or `{ portal, when }` (a brand portal page; `when` is `now` or `after_go_live`).
properties:
tool:
type: string
args:
type: object
additionalProperties: true
portal:
type: string
when:
type: string
enum:
- now
- after_go_live
blockers:
type: array
description: For a program's readiness item, the checks that stop it being published, with the readiness check's own messages.
items:
type: object
properties:
code:
type: string
message:
type: string
guide:
type: string
ErrorEnvelope:
description: 'Failure shape. NOTE: most modules use `message`; programs endpoints use `error`. Read both. Some errors include a machine-readable `code` and/or a `data` payload.'
type: object
properties:
success:
type: boolean
enum:
- false
message:
type: string
error:
type: string
code:
type: string
data: {}
responses:
Forbidden:
description: Authenticated but not permitted (insufficient scope, wrong role, or FUSE feature not enabled)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
NotFound:
description: Resource not found (or not owned by the key's clinic)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
BadRequest:
description: Bad request / business-rule failure (may include a `code`)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
Unauthorized:
description: Missing, invalid, inactive, or expired API key (or JWT)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: x-api-key
description: Clinic-scoped API key. Keep server-side; never expose in a browser or app bundle.
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: FUSE brand-admin JWT (from POST /auth/signin). Used ONLY by the key-management endpoints — the external /api/v1 surface never accepts JWTs, and API keys never work on key management.