Platform & API

One platform. Every touchpoint.

One API key. Register your customers and their kits, hear when results are ready, then pull DNA and epigenetic results and branded PDFs straight into your own systems.

The model

Everything hangs off your organisation.

Your API key belongs to an admin account in your organisation. Every call runs as that account, so the users you register are created inside your organisation and you only ever see your own people. No organisation code needed.

OrganisationYou
  • API key and admin users
  • Webhook settings
  • Branded PDF settings
  • Plan and report pricing
UserYour client
  • Name, date of birth
  • Language
  • App account
Sample kitKit ID
  • Assigned to a user
  • Status notifications
ProfileDNA or epigenetic
  • Sections and algorithms
  • AI summaries
  • Product recommendations
OutputsFor your product
  • JSON results
  • Branded PDF
  • Webhook events
Results powerYour app or portalMAISIELifestyle PlansDynamic ReportsBranded PDFsYour data warehouse
Try the flow

From sign-up to results, one call at a time.

Click through a real integration: register a client, assign her kit, follow the webhooks as the lab works, then pull her results and a branded PDF. Endpoints, events and fields are real; values are examples.

Your system
Simulate the lab

Start by registering Jane, a new client. You can pass her kit IDs here too.

Your systemAPI client + webhook endpoint
  • Jane Doeuser_id 3f2b…
  • Kit ABC123456Assigned
  • Results in your app
  • Branded PDFDownload link from pdf_ready
Muhdo APIYour organisation
  • User createdIn your organisation
  • Kit assignedLinked to Jane
  • Sample trackedStatus history kept
  • Profile readySections, scores, AI summaries
  • PDF generatedWith your PDF settings
LabAccredited lab

Waiting for Jane's sample

ActivityRequests, responses and webhooks

Nothing yet. Press 1 Register user or Play the whole flow.

Example values. Webhooks go to the HTTPS URLs you set in the Helix Portal; the base URL and your key are shared when you're onboarded.
Authentication

One key. Scoped to you.

Every request

API key header

Send your key in an x-api-key header (apikey and api-key also work). Missing or wrong key: 401.

Permissions

Organisation admin

Calls run as the account that owns the key. Registering and updating users needs organisation admin access, and anything outside your organisation comes back as not found.

Security

Keep it server-side

Your key acts as your organisation admin account. Keep it on your servers, never in a browser or mobile app.

Example calls

Built to plug in.

Real endpoints and field names from our partner API. Values are examples.

  • JSON in, JSON out, with snake_case fields
  • Results in your user's language with language_code
  • Safe to repeat: registering a kit to the same user again returns 200
  • A 409 "profile-generating" just means try again shortly
The base URL and your API key are shared when you're onboarded.
POST /v1/register-user
x-api-key: <your_api_key>

{
  "email": "jane.doe@example.com",
  "first_name": "Jane",
  "last_name": "Doe",
  "dob": { "day": 14, "month": 3, "year": 1988 },
  "language_code": "en",
  "sample_kit_ids": ["ABC123456"]
}

→ 200 OK
{
  "success": true,
  "user_id": "3f2b…",
  "kit_ids": ["ABC123456"],
  "failed_kits": []
}
POST /v1/register-sample-kit
x-api-key: <your_api_key>

{
  "email": "jane.doe@example.com",
  "kit_id": "ABC123457"
}

→ 200 OK
{ "success": true, "email": "jane.doe@example.com", "kit_id": "ABC123457" }

Same user again: 200. Someone else's kit: 409.
POST /v1/user
x-api-key: <your_api_key>

{ "user_id": "3f2b…" }

→ 200 OK
{
  "first_name": "Jane", "last_name": "Doe",
  "sample_kits": [{
    "kit_id": "ABC123456",
    "dna_profiles": [{ "id": "2a7d…", "date_generated": "…" }],
    "epigenetic_profiles": [],
    "notifications": [{ "kit_status": "Sample received" }]
  }]
}
POST /v1/epigenetic-profile
x-api-key: <your_api_key>

{ "profile_id": "9c40…", "language_code": "en" }

→ 200 OK
{
  "kit_id": "ABC123456",
  "epigenetic_sections": [{
    "name": "…",
    "algorithms": [{
      "name": "MethylPace",
      "score_results": [{ "score_title": "…", "plain_outcome": "…" }],
      "ai_outcome_summary": "…",
      "product_recommendations": […]
    }]
  }]
}

409 "profile-generating": not ready yet
POST /v1/dna-profile-pdf
x-api-key: <your_api_key>

{
  "profile_id": "2a7d…",
  "pdf_settings_reference_code": "your-branded-pdf"
}

→ 200 OK
{ "job_id": "e51f…" }

Then, to your webhook:
{
  "event_type": "pdf_ready",
  "job_id": "e51f…",
  "url": "https://…pdf",
  "expires": "…"
}
Example values
Endpoint reference

Partner API v1.

Every endpoint takes your x-api-key header and returns JSON. The base URL is shared when you're onboarded.

Users

POST/v1/register-userCreate a user in your organisation
Send
  • email, first_name, last_name
  • dob (day, month, year), gender
  • language_code
  • sample_kit_ids (optional)
Get back
  • success, user_id, email
  • kit_ids assigned
  • failed_kits with a reason for each

Kit IDs are checked before the user is created. The user joins your organisation and its default clinics.

POST/v1/userGet a user
Send
  • user_id
Get back
  • Name, email, date of birth, language, height
  • sample_kits with their DNA and epigenetic profiles
  • Kit status notifications with dates

Handy for polling if you don't use webhooks.

PUT/v1/userUpdate a user
Send
  • user_id
  • Any of first_name, last_name, gender, language_code, dob

Omitted fields stay as they are. Email can't be changed.

Get back
  • The updated user, as in Get a user

Sample kits

POST/v1/register-sample-kitAssign a kit to a user
Send
  • email of the kit owner (leave out to register to your own account)
  • kit_id (spaces are removed)
Get back
  • success, email, kit_id

Repeating for the same owner returns 200. A kit owned by someone else returns 409.

GET/v1/sample-kit-profilesAll your kits and their profiles
Send

Nothing.

Get back
  • sample_kits: kit_id, email, added
  • dna_profiles and epigenetic_profiles, each with profile_id
POST/v1/sample-kit-profilesProfiles for one kit
Send
  • kit_id
Get back
  • The kit, with its DNA and epigenetic profile_ids and dates

Results

POST/v1/dna-profileFull DNA results
Send
  • profile_id
  • language_code
Get back
  • dna_sections, each with an AI section summary
  • Algorithms with outcome, score gauge and SNPs
  • AI-written outcomes and product recommendations
  • Ancestry results where included

In the requested language where available. 409 while still generating.

POST/v1/epigenetic-profileFull epigenetic results
Send
  • profile_id
  • language_code
Get back
  • epigenetic_sections and algorithms
  • score_results with plain and AI outcomes
  • AI summary and product recommendations

409 while still generating.

Branded PDFs

POST/v1/dna-profile-pdfBranded DNA PDF
Send
  • profile_id
  • pdf_settings_reference_code for your branding
Get back
  • job_id

The pdf_ready webhook sends the same job_id with the download link and expiry.

POST/v1/epigenetic-profile-pdfBranded epigenetic PDF
Send
  • profile_id
  • pdf_settings_reference_code
Get back
  • job_id, then pdf_ready with the link
Webhooks

Don't poll. We'll tell you.

Add an HTTPS URL, with your own headers, for each event in the Helix Portal (Organisation Admin, then Webhooks), and send a test delivery to check it. Profile and PDF webhooks can be set per test type.

User registereduser_registeredA new user joins your organisation.
Kit registeredsample_kit_registeredA kit is assigned to a user.
Kit statussample_statusThe kit moves on, for example "Sample received".
Results readyprofile_readyA DNA or epigenetic profile is ready to pull.
PDF readypdf_readyYour branded PDF, with its job_id, link and expiry.
POST to your URL
// sample_status
{
  "event_type": "sample_status",
  "kit_id": "ABC123456",
  "kit_status": "Sample received",
  "date_time": "2026-11-20T09:30:00Z"
}

// profile_ready
{
  "event_type": "profile_ready",
  "profile_id": "9c40…",
  "algorithm_set_name": "…",
  "date_time": "…"
}
Example values
  • HTTPS, public endpointsDeliveries go to HTTPS URLs on public addresses.
  • Any 2xx countsWe wait up to 30 seconds for your reply.
  • Automatic retriesUp to 5 attempts in total, about 5 minutes, 30 minutes, 2 hours and 6 hours after a failure.
  • Secure it your wayAdd a secret custom header, check it on arrival, and make your handler safe to run twice.
  • UTC timesWebhook date_time values are in UTC.
Errors

Plain status codes, short messages.

Errors come back as a short JSON string with the matching HTTP status. Branch on the status and log the message.

StatusWhat it means
200Success
400Validation failed, for example a bad date of birth or language code
401Missing or invalid API key
403Not an organisation admin, or no access to that user
404Not found, or outside your organisation
409Results still generating, or the kit belongs to someone else
Codes you'll see
missing-user-idmissing-kit-idinvalid-first-nameinvalid-last-nameinvalid-dobinvalid-genderinvalid-language-codeforbiddennot-foundprofile-generatingunexpected-error
Questions

Good to know.

How do we get access?

Book a call. We set up your organisation and an admin account with its API key, share the base URL, and agree your DNA and epigenetic test sets and PDF branding.

Can we order kits through the API?

No. The API registers kits you already have. Kits are ordered through the wholesale shop or your account manager.

Do we have to use the API?

No. Many partners run everything through the app and the Helix Portal. The API is there when you want results inside your own product.

Can results come back in our users' languages?

Yes. Send a language_code when you register a user or request a profile.

Can we brand the PDFs?

Yes. PDFs are generated with your organisation's PDF settings, picked by pdf_settings_reference_code.

What happens to client data?

Every call is scoped to your organisation, genetic data is protected and consent-led, every sample is tracked with a full chain of custody, and clients can ask for their data to be deleted at any time.

Next step

Let's build it together.

Pick the pieces you need, send them over, and we'll come back with a proposal.