Color Samples API
Lab/LIMS sample lifecycle: accession, result reporting, destruction.
Lab/LIMS sample lifecycle: accession, result reporting, destruction.
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/color-samples-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: External API V1 Samples API
description: Color Health's External API V1 — the partner-facing REST API behind docs.color.com/reference. It lets benefit administrators and lab/LIMS partners manage eligibility entries for their populations, upload eligibility files, query participants, results, samples and self-reported results, and (for lab partners) accession, report and destroy test samples. Authentication is a Color-issued bearer token supplied in the Authorization header; staging and production use separate tokens.
termsOfService: https://www.color.com/tos/
contact:
email: dev@color.com
name: Color Health API Support
url: https://docs.color.com/reference
license:
name: private
version: v1
servers:
- url: https://api.color.com/api/v1/external
description: Production
security:
- Bearer: []
tags:
- name: samples
description: 'Lab/LIMS sample lifecycle: accession, result reporting, destruction.'
paths:
/samples/{sample_barcode}/accession:
post:
tags:
- samples
description: This endpoint records that a sample has arrived at the lab. If the sample was previously accessioned by the caller, its status will not be modified (the endpoint is idempotent).
parameters:
- name: sample_barcode
description: Barcode included in the test collection kit
in: path
required: true
schema:
type: string
pattern: ^D-\d{10}$
responses:
'200':
description: If the sample was accessioned successfully, or has been previously accessioned by the caller, this endpoint will return a JSON object with information about the requested sample.
content:
application/json:
schema:
type: object
properties:
accession_number:
type: string
description: The sample’s accession number ( e.g. ‘C-12345’ )
example: C-12345
collected_at:
type: string
format: date-time
description: An iso-formatted collection timestamp (e.g. '2020-04-28T04:33:22.111111+00:00'). This field may be null if is_approved_for_processing is false
example: '2022-05-31T16:42:48.840Z'
is_approved_for_processing:
type: boolean
description: This field will be true if the sample is approved to be tested. It can be false for multiple reasons - e.g. if the sample’s order is cancelled or the sample doesn’t have an order. If this field is false, the sample should be discarded.
sample_type:
type: string
description: 'The swab type. All covid samples start out with the sample type ‘covid_swab’, which is then updated to a more specific type when an order is placed for the sample. So if you receive a sample without an order, it will have the type ‘covid_swab’. Otherwise, all samples with orders should have one of the more detailed sample types.
Possible values include:
* `covid_dry_anterior_nares_swab`
* `covid_anterior_nares_swab`
* `covid_nasopharyngeal_swab`
* `covid_oropharyngeal_swab`
* `covid_swab`'
enum:
- covid_dry_anterior_nares_swab
- covid_anterior_nares_swab
- covid_nasopharyngeal_swab
- covid_oropharyngeal_swab
- covid_swab
shipping_batch_id:
description: The ID of the batch in which the sample arrived at the lab. Will be null if the sample isn’t assigned to a shipping batch.
type: string
example: 1234
result_type:
description: 'The test type of the sample. Can be one of:
* `surveillance`
* `diagnostic`'
type: string
enum:
- surveillance
- diagnostic
organization_name:
description: The name of the organization that the sample is associated with. This field may be null if `is_approved_for_processing` is false.
type: string
customer_account_name:
description: The name of the customer account that the organization is associated with.
type: string
rejection_reason:
description: 'The reason why the sample is not approved for processing. Will be null if `is_approved_for_processing` is false.
Possible values include:
* `SAMPLE_DECOMMISSIONED` - if the sample was decommissioned.
* `SAMPLE_EXPIRED` - if the lab has a configured accessioning policy and the sample is considered expired.
* `SAMPLE_NOT_ACTIVATED` - if there is an order for the sample but the sample wasn''t activated.
* `ORDER_CANCELLED` - if all of the sample''s orders were cancelled.
* `NO_ORDER` - if the sample has no valid orders supporting its processing.'
type: string
enum:
- ORDER_CANCELLED
- NO_ORDER
- SAMPLE_NOT_ACTIVATED
- SAMPLE_EXPIRED
- SAMPLE_DECOMMISSIONED
examples:
response:
value:
accession_number: C-12345
collected_at: '2020-04-28T04:33:22.111111+00:00'
is_approved_for_processing: true
organization_name: Acme Processing
sample_type: covid_dry_anterior_nares_swab
shipping_batch_id: '1234'
result_type: surveillance
customer_account_name: Color
rejection_reason: 'null'
'400':
description: In some extremely rare cases, it may not be possible for us to mark the sample as accessioned. This can occur if the sample has already been accessioned by a different lab or if there is an internal issue in Color’s system. In this case, the response will have a status code of 400 and the response body will have an ’error’ property with information about the problem.
content:
application/json:
schema:
type: object
properties:
error:
type: object
properties:
code:
type: string
enum:
- SAMPLE_NOT_PROVISIONED
- SAMPLE_ALREADY_ACCESSIONED
- WRONG_SAMPLE_TYPE_FOR_LAB
description: '* `SAMPLE_NOT_PROVISIONED` - This code means that we don’t have a record of the sample being sent to a collection site.
* `SAMPLE_ALREADY_ACCESSIONED` - This code means that the sample has already been accessioned by a different lab.
* `WRONG_SAMPLE_TYPE_FOR_LAB` - This error code means that the sample isn’t one of the swab types that we know your lab can process. For example, if your lab was listed in Color''s system as only able to process anterior nares swabs, you would receive this error code if you attempted to accession an oropharyngeal swab. This error code could mean that you’ve received a sample that shouldn’t have been sent to you, or it could mean that the swab is listed as the wrong type in Color’s database.'
message:
type: string
examples:
response:
value:
code: SAMPLE_NOT_PROVISIONED
message: Sample was not properly provisioned
'404':
description: The sample wasn't found in Color's database (i.e. the barcode was invalid)
'500':
description: An error has occurred, please try again after a few minutes.
operationId: samples_accession_create
summary: Record that a sample arrived at the lab
/samples/{sample_barcode}/results:
post:
tags:
- samples
description: This endpoint records the test result for a sample. If the result has already been reported (identified by the assay and the completion time), nothing happens (the endpoint is idempotent).
parameters:
- name: sample_barcode
description: Barcode included in the test collection kit
in: path
required: true
schema:
type: string
pattern: ^D-\d{10}$
requestBody:
content:
application/json:
schema:
type: object
required:
- significance
- assay_type
- time_completed
properties:
batch_id:
description: Any unique identifier per lab batch, e.g. a plate ID. Used for sample tracking and investigations.
type: string
example: Plate 1
significance:
type: string
description: 'Possible values include:
* `NEG` - Negative for SARS-CoV2
* `INCONCLUSIVE` - Inconclusive for SARS-CoV2
* `POS` - Positive for SARS-CoV2
* `INVALID` - Assay failed twice
* `UNSATISFACTORY_1` - Improper specimen transport medium
* `UNSATISFACTORY_2` - Inappropriate timing of collection relative to specimen receipt
* `UNSATISFACTORY_3` - Sample tube unlabeled
* `UNSATISFACTORY_4` - Insufficient volume
* `UNSATISFACTORY_5` - Tube sample data does not match the submission form
* `UNSATISFACTORY_6` - Laboratory accident
* `UNSATISFACTORY_7` - Leaking/broken tube (wet swabs)
* `UNSATISFACTORY_8` - Sample not received
* `UNSATISFACTORY_9` - Incomplete requisition
* `UNSATISFACTORY_10` - Leaking/broken tube (dry swabs)
* `UNSATISFACTORY_11` - Sample could not be processed
* `UNSATISFACTORY_12` - Swab collection not up to standards
* `UNSATISFACTORY_13` - Unable to process due to sample viscosity
* `UNSATISFACTORY_14` - Sample not processed due to overpackaging
* `UNSATISFACTORY_15` - Inverted swab
* `UNSATISFACTORY_16` - Incorrect number of swabs for result type'
enum:
- NEG
- INCONCLUSIVE
- POS
- INVALID
- UNSATISFACTORY_1
- UNSATISFACTORY_2
- UNSATISFACTORY_3
- UNSATISFACTORY_4
- UNSATISFACTORY_5
- UNSATISFACTORY_6
- UNSATISFACTORY_7
- UNSATISFACTORY_8
- UNSATISFACTORY_9
- UNSATISFACTORY_10
- UNSATISFACTORY_11
- UNSATISFACTORY_12
- UNSATISFACTORY_14
- UNSATISFACTORY_15
- UNSATISFACTORY_16
cycle_thresholds:
description: "(optional): An array of cycle thresholds (Ct) for the sample. Only applicable for RT-PCR tests. Each item in the array requires:\n - gene: The name of the gene this threshold applies to.\n - value: The threshold value as a floating point number."
items:
type: object
properties:
gene:
minLength: 1
title: Gene
type: string
value:
format: decimal
title: Value
type: string
type: array
assay_type:
description: Assay type can either be LAMP, RT-PCR, and in some cases, specific value(s) defined by Color
type: string
enum:
- LAMP
- RT-PCR
time_completed:
description: ISO-formatted timestamp representing when the test was completed.
type: string
format: date-time
example: '2022-05-31T16:42:48.840Z'
description: The sample result
responses:
'200':
description: Result was recorded successfully
'400':
description: 'Result could not be recorded. Potential errors which could be returned with a 400 include:
* "Sample {sample_barcode} is not approved for processing"
* "Sample {sample_barcode} is not accessioned"'
'404':
description: The sample wasn't found in Color's database (i.e. the barcode was invalid)
'500':
description: An error has occurred, please try again after a few minutes.
operationId: samples_results_create
summary: Record a test result for a sample
/samples/{sample_barcode}/destroy:
post:
tags:
- samples
description: This endpoint records that an unapproved sample is being destroyed by the lab. If the sample was already destroyed, nothing happens (the endpoint is idempotent).
parameters:
- name: sample_barcode
description: Barcode included in the test collection kit
in: path
required: true
schema:
type: string
pattern: ^D-\d{10}$
responses:
'200':
description: The sample was successfully marked as destroyed
'400':
description: The sample cannot be destroyed since it it approved for processing.
'404':
description: The sample wasn't found in Color's database (i.e. the barcode was invalid)
'500':
description: An error has occurred, please try again after a few minutes.
operationId: samples_destroy_create
summary: Record that an unapproved sample was destroyed
components:
securitySchemes:
Bearer:
in: header
name: Authorization
type: apiKey