Skip to content

Kit Ordering Integration Guide

Feature Availability

The Kit Ordering feature is enabled on demand. If you're interested in using this feature to enable direct-to-consumer genetic testing through your application, please contact Gencove support to have it enabled for your organization.

Overview

The Kit Ordering integration allows your application to programmatically order genetic testing kits for your end-users through Gencove's API.

Prefer not to build the order form?

If you'd rather have your end-users enter their own shipping details on a Gencove-hosted page instead of collecting the address in your application, see Gencove-Hosted Kit Ordering Form below.

Key Concepts

Before integrating, it's helpful to understand a few core Gencove concepts:

  • Sample: Represents a single genetic sample in Gencove. In the kit ordering workflow, one kit order equals one sample. The kit is what physically carries a sample. Each sample has a unique ID and tracks the entire lifecycle from kit request through sequencing and analysis.
  • Sample Status: Samples progress through various states (e.g., kit requested, kit ordered, kit received at lab, running, succeeded). The full list is in Sample Status Lifecycle.
  • Project: A container for organizing related samples in Gencove. All samples from kit orders must be assigned to a project.

How It Works

The kit ordering workflow involves four key parties:

  1. Your end-user: The person requesting a genetic testing kit
  2. Your application (consumer health company): Handles user requests and integrates with Gencove's API
  3. Gencove: Orchestrates the kit ordering and processes sequencing results
  4. Sequencing provider: Manufactures, ships, receives, and sequences the kits
sequenceDiagram
    autonumber
    actor EU as End-user
    participant CC as Consumer company
    participant GC as Gencove
    participant SP as Sequencing provider

    EU->>CC: Orders kit
    CC->>CC: Accept request, store information
    Note over CC,GC: CC uses Gencove API key for the request
    CC->>GC: POST https://api.gencove.com/api/v2/sample-kit/
    GC-->>CC: Return Gencove sample ID
    GC->>SP: Pass order information
    SP-->>EU: Ship kit to end-user
    EU-->>SP: Return kit
    SP->>SP: Process kit (sequencing)
    SP->>GC: Send sequencing results
    GC->>GC: Process results (Gencove analysis)

    alt Delivery back to CC via webhook
        GC-->>CC: POST results (webhook)
    else Delivery back to CC via API pull
        CC->>GC: Fetch results (API)
        GC-->>CC: GET https://api.gencove.com/api/v2/samples/{sample id}
    end

    CC-->>EU: Display results in application
sequenceDiagram
    autonumber
    actor EU as End-user
    participant CC as Consumer company
    participant GC as Gencove
    participant SP as Sequencing provider

    EU->>CC: Orders kit
    CC->>CC: Accept request, store information
    Note over CC,GC: CC uses Gencove API key for the request
    CC->>GC: POST https://api.gencove.com/api/v2/sample-kit/
    GC-->>CC: Return Gencove sample ID
    GC->>SP: Pass order information
    SP-->>EU: Ship kit to end-user
    EU-->>SP: Return kit
    SP->>SP: Process kit (sequencing)
    SP->>GC: Send sequencing results
    GC->>GC: Process results (Gencove analysis)

    alt Delivery back to CC via webhook
        GC-->>CC: POST results (webhook)
    else Delivery back to CC via API pull
        CC->>GC: Fetch results (API)
        GC-->>CC: GET https://api.gencove.com/api/v2/samples/{sample id}
    end

    CC-->>EU: Display results in application

Workflow Steps

  1. Kit Request: Your end-user clicks "Order kit" in your application
  2. Accept Request: Your application accepts the request and stores necessary information
  3. Create Order: Your application makes an authenticated request to Gencove's API to create the kit order
  4. Sample ID: Gencove returns a unique sample ID that you should store to track this kit/sample
  5. Order Processing: Gencove passes the order information to the sequencing provider
  6. Kit Shipment: The sequencing provider ships the kit directly to your end-user's address
  7. Kit Return: Your end-user collects their sample and returns the kit to the sequencing provider
  8. Sequencing: The sequencing provider processes and sequences the sample
  9. Results to Gencove: The sequencing provider sends raw sequencing data to Gencove
  10. Gencove Analysis: Gencove runs its analysis pipeline on the sequencing data
  11. Results Delivery via Webhook: (RECOMMENDED) Gencove delivers results to your application via webhook when they're ready
  12. Fetch results via API: Periodically ping Gencove API to get results
  13. Results response: Use response to check if samples are ready
  14. Display Results: Your application displays the results to your end-user

Integration Guide

Get Your API Key

To make requests to Gencove's API, you'll need an API key. This key authenticates your application and should be kept secure (treat it like a secret or a password).

To generate an API key:

  1. Log in to your Gencove account at web.gencove.com
  2. In the left sidebar, click on Account
  3. Navigate to the API Keys tab
  4. Click the Generate new API key button
  5. Copy the generated API key and store it securely

Security Best Practice: For production use, consider creating a separate Gencove user with Analyst level privileges specifically for API access, and use that user's API key. This follows the principle of least privilege and makes it easier to manage access if needed.

Keep Your API Key Secret

Your API key provides access to your Gencove account. Never commit it to version control, never share it publicly, never expose it in client-side code. Store it in a secure secrets management system. If your key gets exposed, make sure to revoke it immediately and generate a new one.

Create a Gencove Project

Before ordering kits, you need at least one project to assign samples to.

Gencove support should have created a properly configured project during onboarding, if not please contact our team.

Order a Kit

When your end-user requests a kit, your application should make a POST request to Gencove's kit ordering endpoint.

API Endpoint: POST https://api.gencove.com/api/v2/sample-kit/

Authentication: Include your API key in the Authorization header: Authorization: Api-Key $GENCOVE_API_KEY

Request Body:

{
  "project_id": "<project-uuid>",
  "recipient_address_name": "Jane Doe",
  "recipient_address_line1": "123 Main Street",
  "recipient_address_city": "San Francisco",
  "recipient_address_state_region": "CA",
  "recipient_address_postal_code": "94102",
  "recipient_address_country_code": "US",
  "recipient_email": "jane.doe@example.com",
  "recipient_phone": "+14155551234",
  "recipient_instructions": "Leave at front desk",
  "metadata": {
    "customer_id": "cust_12345",
    "order_number": "ORD-2025-001"
  }
}

Required Fields:

  • project_id: The UUID of the Gencove project to assign this sample to
  • recipient_address_name: Full name of the kit recipient
  • recipient_address_line1: Street address
  • recipient_address_city: City name
  • recipient_address_state_region: State or region
  • recipient_address_postal_code: Postal/ZIP code
  • recipient_address_country_code: Two-letter ISO country code (e.g., "US", "GB", "CA")
  • recipient_email: Email address for shipping notifications
  • recipient_phone: Phone number (international format recommended)

Optional Fields:

  • recipient_address_line2: Additional address information (apartment, suite, etc.)
  • recipient_address_line3: Additional address information
  • recipient_instructions: Special delivery instructions
  • metadata: Custom key-value pairs to store with the sample (useful for linking back to your system)
  • test_mode: Boolean flag for development testing (see Test Mode below)

Response:

{
  "sample_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}

Important: Store the returned sample_id in your database. This is the unique identifier you'll use to track the kit's status and retrieve results. Alternatively, if you include information in the metadata field when creating the order, you can search for samples using that metadata to find the correct sample without storing the sample ID.

Note that the response contains no kit ID: the sample is created immediately, but the kit ID (the code printed on the physical kit) does not exist yet at this point. The sequencing provider assigns it later, while fulfilling the order — see Kit ID and Shipment Tracking.

Test Mode

Use Test Mode During Development

When integrating with the Kit Ordering API, use test_mode: true to validate your integration without incurring kit ordering costs or triggering actual shipments.

Test mode allows you to create kit orders that go through the full API validation and workflow, but use a staging environment with the sequencing provider. No physical kit will be manufactured or shipped when test_mode is enabled.

When to use test mode:

  • During initial integration development
  • When testing your order creation flow
  • When validating address formats and API responses

What happens in test mode:

  • The API validates all fields exactly as in production
  • A sample is created in your Gencove project with status kit requested
  • The order is sent to the provider's staging environment
  • The sample will progress to kit ordered status
  • No physical kit is shipped and no kit ordering costs are incurred
  • The sample will not receive sequencing results (since no kit is shipped)
  • The kit details endpoint returns "test_mode": true for the sample (see Kit ID and Shipment Tracking)

To enable test mode, simply add "test_mode": true to your request body:

{
  "project_id": "<project-uuid>",
  "recipient_address_name": "Jane Doe",
  "recipient_address_line1": "123 Main Street",
  "recipient_address_city": "San Francisco",
  "recipient_address_state_region": "CA",
  "recipient_address_postal_code": "94102",
  "recipient_address_country_code": "US",
  "recipient_email": "jane.doe@example.com",
  "recipient_phone": "+14155551234",
  "test_mode": true
}

Test Mode Samples

Samples created with test_mode: true will never complete the full workflow since no physical kit is shipped. These samples are useful for testing your integration but should not be used for production tracking. Consider using a separate test project to keep test samples organized.

curl -X POST "https://api.gencove.com/api/v2/sample-kit/" \
  -H "Authorization: Api-Key $GENCOVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "06a5d04b-526a-4471-83ba-fb54e0941758",
    "recipient_address_name": "Jane Doe",
    "recipient_address_line1": "123 Main Street",
    "recipient_address_city": "San Francisco",
    "recipient_address_state_region": "CA",
    "recipient_address_postal_code": "94102",
    "recipient_address_country_code": "US",
    "recipient_email": "jane.doe@example.com",
    "recipient_phone": "+14155551234",
    "metadata": {
      "customer_id": "cust_12345"
    }
  }'
# Use test_mode for development - no kit will be shipped
curl -X POST "https://api.gencove.com/api/v2/sample-kit/" \
  -H "Authorization: Api-Key $GENCOVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "06a5d04b-526a-4471-83ba-fb54e0941758",
    "recipient_address_name": "Jane Doe",
    "recipient_address_line1": "123 Main Street",
    "recipient_address_city": "San Francisco",
    "recipient_address_state_region": "CA",
    "recipient_address_postal_code": "94102",
    "recipient_address_country_code": "US",
    "recipient_email": "jane.doe@example.com",
    "recipient_phone": "+14155551234",
    "test_mode": true
  }'
import os

import requests

API_KEY = os.getenv('GENCOVE_API_KEY')
PROJECT_ID = "67931e57-c374-4c0b-9616-8b809ad5b657"

headers = {
    "Authorization": f"Api-Key {API_KEY}",
    "Content-Type": "application/json"
}

payload = {
    "project_id": PROJECT_ID,
    "recipient_address_name": "Jane Doe",
    "recipient_address_line1": "123 Main Street",
    "recipient_address_city": "San Francisco",
    "recipient_address_state_region": "CA",
    "recipient_address_postal_code": "94102",
    "recipient_address_country_code": "US",
    "recipient_email": "jane.doe@example.com",
    "recipient_phone": "+14155551234",
    "metadata": {
        "customer_id": "cust_12345"
    }
}

response = requests.post(
    "https://api.gencove.com/api/v2/sample-kit/",
    headers=headers,
    json=payload
)

sample_id = response.json()["sample_id"]
print(f"Kit ordered! Sample ID: {sample_id}")
import os

import requests

API_KEY = os.getenv('GENCOVE_API_KEY')
PROJECT_ID = "67931e57-c374-4c0b-9616-8b809ad5b657"

headers = {
    "Authorization": f"Api-Key {API_KEY}",
    "Content-Type": "application/json"
}

# Use test_mode=True for development - no kit will be shipped
payload = {
    "project_id": PROJECT_ID,
    "recipient_address_name": "Jane Doe",
    "recipient_address_line1": "123 Main Street",
    "recipient_address_city": "San Francisco",
    "recipient_address_state_region": "CA",
    "recipient_address_postal_code": "94102",
    "recipient_address_country_code": "US",
    "recipient_email": "jane.doe@example.com",
    "recipient_phone": "+14155551234",
    "test_mode": True,  # Enable test mode
}

response = requests.post(
    "https://api.gencove.com/api/v2/sample-kit/",
    headers=headers,
    json=payload
)

sample_id = response.json()["sample_id"]
print(f"Test kit ordered! Sample ID: {sample_id}")

Monitor Kit Status

After ordering a kit, you can monitor its progress through various stages. Each transition is recorded as a sample status with a timestamp. The current status is returned as last_status on the sample endpoints; the full history is available from the status history endpoint.

Sample Status Lifecycle

In the normal case a kit sample passes through the following statuses, in this order:

kit requestedkit orderedkit shippedkit arrived at labkit received at labkit result addedkit completed at labscheduledimporting …runningsucceeded

The tables below list the exact status strings returned by the API. In each table the normal path comes first, followed by holds and failure states. Statuses marked not always recorded are brief lab steps that may be skipped.

Ordering and shipping

Status Meaning
kit requested Order accepted by Gencove and being passed to the sequencing provider. First status on the sample.
kit ordered Order accepted by the sequencing provider. provider_kit_id becomes available shortly after (see Kit ID and Shipment Tracking).
kit shipped Kit handed to the carrier for delivery to your end-user. The tracking_* fields on the kit details endpoint are populated.
kit order failed wrong address The sequencing provider rejected the shipping address; no kit was ordered. The provider's validation message is in the status note. Place a new order with a corrected address, or contact support.

At the sequencing lab

After your end-user mails the kit back, the sample stays at kit shipped until the lab has it. The lab's processing stages are then reflected in the sample status:

Status Meaning
kit arrived at lab Returned kit checked in at the lab. Not always recorded; a sample can go straight to kit received at lab.
kit received at lab The lab has the kit and has started processing it (DNA extraction and sequencing).
kit result added Sequencing done; raw data attached by the lab. Not always recorded.
kit completed at lab Lab processing finished; raw data is being handed over to Gencove.
kit 10 day delay Hold. The first sequencing attempt did not meet the lab's quality or coverage requirements and the sample is being re-run, adding roughly 10 business days (about two weeks) to turnaround. No action is needed; the sample stays at this status until the lab reports the next stage.
kit new collection requested Hold. The lab could not obtain usable data from the sample (for example repeated QC failure or a damaged collection tube); a new sample collection is required. Contact support to arrange it.
kit canceled Lab order canceled; the kit will not be processed and no results will be delivered. Final.

Gencove analysis

Status Meaning
scheduled Raw sequencing data received by Gencove; queued for analysis.
importing … Raw data being ingested. The exact status name depends on the data type (for example importing from s3 cram).
running Analysis in progress.
succeeded Analysis complete; results are ready. Final.
failed qc and other failed … statuses Analysis or QC failure. Final. Rare; contact support if this occurs.

Samples created through the Gencove-Hosted Kit Ordering Form pass through two extra statuses before kit requested, listed in Additional Sample Statuses.

Check Current Status

curl "https://api.gencove.com/api/v2/samples/$SAMPLE_ID/" \
  -H "Authorization: Api-Key $GENCOVE_API_KEY"
import os

import requests

API_KEY = os.getenv('GENCOVE_API_KEY')
SAMPLE_ID = "3fa85f64-5717-4562-b3fc-2c963f66afa6"

headers = {
    "Authorization": f"Api-Key {API_KEY}"
}

response = requests.get(
    f"https://api.gencove.com/api/v2/samples/{SAMPLE_ID}/",
    headers=headers
)

sample_data = response.json()
print(f"Sample status: {sample_data['last_status']['status']}")

Simplified response:

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "client_id": "",
  "provider_kit_id": "GV12345678",
  "last_status": {
    "status": "running",
    "created": "2025-10-31T12:34:56Z"
  },
  "project": "67931e57-c374-4c0b-9616-8b809ad5b657",
  "metadata": {
    "customer_id": "cust_12345"
  }
}

Status History and Timestamps

To see every stage a sample has been through, and when, fetch its status history. Use it to measure turnaround, for example from kit shipped to kit received at lab, or from kit received at lab to succeeded.

API Endpoint: GET https://api.gencove.com/api/v2/sample-statuses/{sample_id}

curl "https://api.gencove.com/api/v2/sample-statuses/$SAMPLE_ID" \
  -H "Authorization: Api-Key $GENCOVE_API_KEY"
import os

import requests

API_KEY = os.getenv('GENCOVE_API_KEY')
SAMPLE_ID = "3fa85f64-5717-4562-b3fc-2c963f66afa6"

headers = {
    "Authorization": f"Api-Key {API_KEY}"
}

response = requests.get(
    f"https://api.gencove.com/api/v2/sample-statuses/{SAMPLE_ID}",
    headers=headers
)

for entry in response.json()["results"]:
    print(f"{entry['created']}  {entry['status']}")

Response:

{
  "meta": {
    "count": 10,
    "next": null,
    "previous": null
  },
  "results": [
    {"status": "kit requested", "note": "", "created": "2025-10-31T12:34:56Z"},
    {"status": "kit ordered", "note": "", "created": "2025-10-31T12:35:02Z"},
    {"status": "kit shipped", "note": "", "created": "2025-11-01T16:20:11Z"},
    {"status": "kit received at lab", "note": "", "created": "2025-11-10T14:02:47Z"},
    {"status": "kit result added", "note": "", "created": "2025-11-19T09:41:30Z"},
    {"status": "kit completed at lab", "note": "", "created": "2025-11-19T09:41:33Z"},
    {"status": "scheduled", "note": "", "created": "2025-11-19T09:42:05Z"},
    {"status": "importing from s3 cram", "note": "", "created": "2025-11-19T09:45:00Z"},
    {"status": "running", "note": "", "created": "2025-11-19T10:15:48Z"},
    {"status": "succeeded", "note": "", "created": "2025-11-19T13:58:12Z"}
  ]
}

  • Entries are ordered oldest first; the last entry is the sample's current status.
  • created is the time Gencove recorded the transition. Order, shipping, lab-completion and hold events reach Gencove within minutes; some intermediate lab stages are picked up by a periodic sync and can be recorded up to a few hours after they happen at the lab.
  • note is empty for most statuses; it carries the provider's message on kit order failed wrong address.
  • The response is paginated like other list endpoints (meta.next links to the next page). A kit sample's history normally fits in one page.

Kit ID and Shipment Tracking

Once the sequencing provider assigns a kit to your order, Gencove exposes the kit ID — the code printed on the physical kit (e.g. GV12345678). Your end-users will typically quote this code when contacting your support, so it is the identifier to look samples up by. Once the kit ships, shipment tracking information becomes available as well.

Kit IDs are assigned by the sequencing provider, not at order time

Creating a kit order creates the sample immediately, but the kit ID does not exist yet at that point. The sequencing provider assigns it while fulfilling the order — typically minutes to hours after the order is placed — and Gencove picks it up automatically. Until then, provider_kit_id is null on all API responses.

Kit ID on sample responses:

Every sample response includes a read-only provider_kit_id field — both the sample detail endpoint shown above and the project samples list (GET /api/v2/project-samples/{project_id}).

You can also search project samples by kit ID: pass a full or partial kit ID as the search query parameter (kit IDs are matched by the default search), or scope the search to kit IDs only with search_by=provider_kit_id.

Kit details endpoint:

For the full kit record, including shipment tracking, fetch the kit details for a sample:

curl "https://api.gencove.com/api/v2/sample-kit/$SAMPLE_ID" \
  -H "Authorization: Api-Key $GENCOVE_API_KEY"
import os

import requests

API_KEY = os.getenv('GENCOVE_API_KEY')
SAMPLE_ID = "3fa85f64-5717-4562-b3fc-2c963f66afa6"

headers = {
    "Authorization": f"Api-Key {API_KEY}"
}

response = requests.get(
    f"https://api.gencove.com/api/v2/sample-kit/{SAMPLE_ID}",
    headers=headers
)

kit_data = response.json()
print(f"Kit ID: {kit_data['provider_kit_id']}")
print(f"Tracking: {kit_data['tracking_url']}")

Response:

{
  "sample_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "provider_kit_id": "GV12345678",
  "test_mode": false,
  "tracking_number": "779279873135",
  "tracking_carrier": "DHL",
  "tracking_url": "https://webtrack.dhlglobalmail.com/?trackingnumber=779279873135",
  "created": "2025-10-31T12:34:56Z"
}

  • provider_kit_id is null until the provider assigns a kit number.
  • The tracking_* fields are null until the kit ships. If the provider re-ships a kit (for example after a lost package), the fields reflect the latest shipment.
  • test_mode mirrors the test_mode flag the order was created with.
  • The endpoint returns 404 when the sample has no kit order.

In the web UI:

On projects using a DTC pipeline configuration, the project samples table shows a "Provider kit ID" column, the sample search offers a "Provider kit ID" option, and the sample page shows a "Kit details" link that opens the kit and tracking details.

Receive Results

Once sequencing and analysis are complete, you need to retrieve the results. Gencove offers two approaches:

Webhooks allow Gencove to automatically notify your application when samples reach a final status (succeeded or failed qc). This is more efficient than polling and provides real-time updates when results are ready.

To set up webhooks see our integration guide.

Option 2: API Polling

If webhooks aren't feasible for your infrastructure, you can periodically poll the samples API to check for status updates.

For polling it's better to use the /project-samples/{project_id} endpoint that can be used for querying many samples at once. See our API reference for a detailed list of endpoints.

Note: If using polling, we recommend checking no more frequently than every 1 hour. Typical turnaround time from order placed to results is measured in weeks.

Gencove-Hosted Kit Ordering Form

The Order a Kit flow above has your application collect the recipient's shipping address and submit it to POST /api/v2/sample-kit/. As an alternative, Gencove can host the order form for you: your backend requests a short-lived, tokenized URL and hands it to the end-user, who enters their own shipping details on a Gencove-hosted page and submits. The kit order is then placed automatically—with no payment step, billed by contract exactly like the API path above.

Use this when you'd rather not build and validate a shipping-address form yourself. Everything else in this guide applies unchanged—getting an API key, creating a project, monitoring status, and receiving results.

How the Hosted Form Works

  1. Your application calls POST /api/v2/sample-kit-form/ with a project_id (no address).
  2. Gencove returns a sample_id and a short-lived url.
  3. You hand the url to your end-user, who opens it, fills in their shipping details, and submits on consumer.gencove.com.
  4. Gencove places the kit order automatically, and the sample proceeds through the same statuses as the API path.

Create an Order-Form Session

When your end-user is ready to order, your application makes a POST request to Gencove's kit-order-form endpoint.

API Endpoint: POST https://api.gencove.com/api/v2/sample-kit-form/

Authentication: Include your API key in the Authorization header: Authorization: Api-Key $GENCOVE_API_KEY

Request Body:

{
  "project_id": "<project-uuid>",
  "metadata": {
    "customer_id": "cust_12345",
    "order_number": "ORD-2025-001"
  },
  "redirect_on_success": "https://partner.example.com/order/done",
  "redirect_on_failure": "https://partner.example.com/order/error",
  "expires_in": 600
}

Required Fields:

  • project_id: The UUID of the Gencove project to assign this sample to

Optional Fields:

  • metadata: Custom key-value pairs stored on the sample (useful for linking back to your system)
  • redirect_on_success: HTTPS URL to send the end-user to after they submit the order; omit to send them to a generic Gencove-hosted confirmation page
  • redirect_on_failure: HTTPS URL to send the end-user to if the order cannot be completed, with a reason query parameter appended; omit to send them to Gencove's hosted error page instead. Only failures Gencove can tie back to this order link reach your URL—see Failure reasons
  • test_mode: Boolean flag for development testing (see Test Mode above); defaults to false
  • expires_in: How long the order-form link stays valid before the end-user opens it, in seconds (default 600 / 10 minutes, minimum 60, maximum 3600)

The shipping address is not part of this request—your end-user enters it on the hosted form.

Response:

{
  "sample_id": "6c3437b4-35fc-4224-9bb0-4623a16e6735",
  "url": "https://consumer.gencove.com/sample-kit-form?token=<jwt>",
  "expires_at": "2026-06-02T12:34:56Z"
}

Important: Store the returned sample_id in your database to track the sample's status and retrieve results. Hand the returned url to your end-user when they are ready to order, opening it as a top-level page (see Opening the Order Form). Create the session shortly before ordering—the link expires after expires_in seconds.

curl -X POST "https://api.gencove.com/api/v2/sample-kit-form/" \
  -H "Authorization: Api-Key $GENCOVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "06a5d04b-526a-4471-83ba-fb54e0941758",
    "metadata": {"customer_id": "cust_12345"},
    "redirect_on_success": "https://partner.example.com/order/done",
    "expires_in": 600
  }'
import os

import requests

API_KEY = os.getenv("GENCOVE_API_KEY")
PROJECT_ID = "06a5d04b-526a-4471-83ba-fb54e0941758"

headers = {
    "Authorization": f"Api-Key {API_KEY}",
    "Content-Type": "application/json",
}

payload = {
    "project_id": PROJECT_ID,
    "metadata": {"customer_id": "cust_12345"},
    "redirect_on_success": "https://partner.example.com/order/done",
    "expires_in": 600,
}

response = requests.post(
    "https://api.gencove.com/api/v2/sample-kit-form/",
    headers=headers,
    json=payload,
)
response.raise_for_status()
session = response.json()
print(f"Sample ID: {session['sample_id']}")
print(f"Order-form URL: {session['url']}")

test_mode works exactly as described in Test Mode above and is passed here at session-creation time; the resulting order goes to the provider's staging environment and no physical kit is shipped.

End-User Order Experience

After your end-user opens the url:

  1. Gencove validates the link and shows the order form on consumer.gencove.com
  2. The end-user enters their shipping details—recipient name, email, phone, address, and any delivery instructions—and submits
  3. Gencove places the kit order automatically; there is no payment step
  4. On success, they are redirected to redirect_on_success, or to a generic Gencove-hosted confirmation page when you did not configure one
  5. If the order cannot be placed, they are redirected to redirect_on_failure with a reason query parameter appended; otherwise they are sent to Gencove's hosted error page (see Failure reasons)

Once the form is submitted, the kit order is placed automatically—you do not need to make a separate API call.

Session timing: The order-form link is valid for expires_in seconds before it is opened. After the end-user opens it, they have 15 minutes to complete and submit the form. If either window expires, create a new session.

Opening the Order Form

Open the returned url as a top-level page. Embedding the order form in an iframe is not supported.

Surface Notes
New browser tab or window Simplest for web applications; open the url with target="_blank"
iOS ASWebAuthenticationSession Returns control to your app when the end-user finishes
Android Custom Tabs Same, on Android
Plain mobile WebView Works, but behaviour varies by platform and configuration—prefer the surfaces above

If you configure redirect_on_success or redirect_on_failure, the end-user lands on your page in that same context when the flow ends, so you can resume your own application's flow there.

Failure Reasons

When an order cannot be completed, the end-user lands on a page with a reason query parameter describing what went wrong. Branch on reason to show the right message in your own UI, and treat an unrecognised value as a generic failure—more may be added over time.

These reasons are sent to your redirect_on_failure:

reason Meaning
link_replaced A newer order-form session was created for this sample, superseding this link
already_ordered The kit for this sample has already been ordered
project_locked The project is locked, so no new order can be placed

These are always shown on Gencove's hosted error page, even if you configured redirect_on_failure:

reason Meaning
link_invalid The order link could not be verified
link_expired The link expired before the end-user opened it
session_expired The end-user opened the link but did not submit within 15 minutes
order_unavailable Kit ordering is no longer enabled for the organization that issued the link

The hosted error page is at https://consumer.gencove.com/sample-kit-form/failure/ and accepts the same reason parameter, so you can open any row above directly—for example https://consumer.gencove.com/sample-kit-form/failure/?reason=already_ordered—to see exactly what your end-user would see, without creating an order-form session first. The confirmation page at /sample-kit-form/success/ works the same way.

Additional Sample Statuses

Hosted-form samples pass through two extra statuses before kit requested (all other statuses match the Sample Status Lifecycle above):

Status Meaning
consumer awaiting kit order Order-form session created; waiting for the end-user to submit
consumer session expired Order-form link expired before the end-user submitted

Manual Testing

You can start an order-form session from the Gencove web UI:

  1. Open your consumer project
  2. Click Order a kit on the project page
  3. Open the returned link, fill in the shipping details, and submit

This uses the same endpoint as the integration described above.

System Responsibilities

Understanding what each system is responsible for helps clarify the integration:

Your Application's Responsibilities

  • Handle end-user requests for kits
  • Collect and validate shipping addresses
  • Store the Gencove sample ID for each kit order
  • Monitor sample status (via webhooks or polling)
  • Retrieve and display results to your end-users
  • Manage your end-users' accounts and permissions
  • Keep the Gencove API Key secure

Gencove's Responsibilities

  • Provide the API for kit ordering
  • Coordinate with the sequencing provider
  • Receive raw sequencing data from the provider
  • Run analysis on the sequencing data
  • Deliver results via webhooks or API
  • Provide sample status tracking

Sequencing Provider's Responsibilities

  • Manufacture and ship kits to end-user addresses
  • Receive returned samples
  • Perform sequencing on samples
  • Deliver raw sequencing data to Gencove

Support

If you have questions about the Kit Ordering integration or encounter any issues: