Overview

The Sample Storage API allows you to view samples stored at the SLP warehouse, create shipment orders to send samples to your processing lab, and track the status of those shipments. Samples are received, inspected, and stored on your behalf until you're ready to ship them.

🛈
Sample Storage Feature This API is only available for customers with sample storage enabled. Contact your account manager to enable this feature.

Authentication

All requests require a valid JWT access token in the Authorization header:

Authorization: Bearer YOUR_ACCESS_TOKEN
  1. Call POST /auth/token with your email and password to get an access token
  2. Include the token in the Authorization header: Bearer <access_token>
  3. When the token expires, use POST /auth/refresh with your refresh token

See the main API docs for full authentication details.

Base URL

EnvironmentBase URLPurpose
Developmenthttps://api.dev.slp-connect.comTesting and integration development
Productionhttps://api.prod.slp-connect.comLive production use
Use Development for Testing Always use the development environment for integration testing. Only use production for live operations with real samples.

List Samples

GET /samples

Returns a paginated list of your stored samples.

Query Parameters

ParameterTypeDescription
limitintegerMax results per page (default: 25, max: 100)
offsetintegerNumber of results to skip (default: 0)
statusstringFilter by status (e.g., stored, shipped)
searchstringSearch by kit ID or sample ID

Example Request

curl "https://api.dev.slp-connect.com/samples?status=stored&limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"

Example Response

{
  "samples": [
    {
      "kit_id": "KIT-10001",
      "id": "4c1cc027-e935-46bc-afad-c830decf96a7",
      "sample_id": "SMP-20001",
      "status": "stored",
      "disposition": "valid",
      "received_at": "2026-04-02T14:55:04.868+00:00",
      "stored_at": "2026-04-02T15:07:18.988+00:00",
      "shipped_at": null,
      "items": { "name": "Collection Kit", "sku": "COLLECT-KIT-01" },
      "orders": { "order_number": "ORD-2026-000209" },
      "location": "S-A-25-1"
    }
  ],
  "total_count": 1,
  "limit": 10,
  "offset": 0,
  "has_more": false
}

Get Sample

GET /samples?kit_id={kitId}

Returns details for a single sample by its kit ID.

Example Request

curl "https://api.dev.slp-connect.com/samples?kit_id=KIT-10001" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response Fields

FieldTypeDescription
kit_idstringUnique kit/tube identifier
sample_idstring | nullSample ID (if applicable)
statusstringCurrent sample status
dispositionstringDisposition from intake (valid, hold, reject, priority)
received_atstringWhen the sample was received (ISO 8601)
stored_atstring | nullWhen the sample was placed in storage
shipped_atstring | nullWhen the sample was shipped to the lab
locationstring | nullStorage location code (null if shipped or destroyed)
itemsobjectItem name and SKU
ordersobjectOriginal outbound order number

Create Sample Shipment

POST /sample-shipments

Create a new shipment order to send stored samples to your processing lab. All specified samples must be in stored status. The shipment will be sent to your configured processing lab address.

Request Body

FieldTypeRequiredDescription
kit_idsstring[]YesArray of kit IDs to include in the shipment
notesstringNoNotes for the shipment

Example Request

curl -X POST https://api.dev.slp-connect.com/sample-shipments \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kit_ids": ["KIT-10001", "KIT-10002", "KIT-10003"],
    "notes": "Batch for March processing"
  }'

Example Response

{
  "shipment": {
    "id": "f95032f1-eff0-4289-a05f-0b2361b78cd2",
    "shipment_number": "SS-2026-000001",
    "status": "created",
    "total_samples": 3,
    "requested_at": "2026-04-03T12:00:00.000Z",
    "kit_ids": ["KIT-10001", "KIT-10002", "KIT-10003"]
  }
}
🛈
What happens next Once created, SLP will pick, pack, and ship the samples to your lab. You'll receive sample.shipped_lab webhook events when the shipment is dispatched.

List Sample Shipments

GET /sample-shipments

Returns a paginated list of your sample shipments.

Query Parameters

ParameterTypeDescription
limitintegerMax results per page (default: 25, max: 100)
offsetintegerNumber of results to skip
statusstringFilter by status (created, packed, shipped, delivered)

Example Response

{
  "shipments": [
    {
      "id": "f95032f1-eff0-4289-a05f-0b2361b78cd2",
      "shipment_number": "SS-2026-000001",
      "status": "shipped",
      "total_samples": 3,
      "tracking_number": "1ZR0829H0446443585",
      "requested_at": "2026-04-03T12:00:00.000Z",
      "shipped_at": "2026-04-03T16:30:00.000Z",
      "ship_to": { "company": "Acme Processing Lab", "city": "Chicago", "state": "IL" }
    }
  ],
  "total_count": 1,
  "limit": 25,
  "offset": 0,
  "has_more": false
}

Get Sample Shipment

GET /sample-shipments/{id}

Returns details for a specific sample shipment, including all samples in the shipment.

Example Response

{
  "shipment": {
    "id": "f95032f1-eff0-4289-a05f-0b2361b78cd2",
    "shipment_number": "SS-2026-000001",
    "status": "shipped",
    "total_samples": 3,
    "tracking_number": "1ZR0829H0446443585",
    "requested_at": "2026-04-03T12:00:00.000Z",
    "packed_at": "2026-04-03T15:00:00.000Z",
    "shipped_at": "2026-04-03T16:30:00.000Z",
    "notes": "Batch for March processing"
  },
  "samples": [
    {
      "kit_id": "KIT-10001",
      "sample_id": "SMP-20001",
      "status": "shipped",
      "disposition": "valid",
      "item_name": "Collection Kit",
      "item_sku": "COLLECT-KIT-01"
    }
  ]
}

Sample Webhook Events

If webhooks are enabled, SLP-Connect sends real-time notifications for sample lifecycle events. These are delivered to your configured webhook URL alongside order and tracking webhooks.

EventTriggerDescription
sample.received Sample received at warehouse A returned sample has been received, inspected, and stored
sample.discarded Sample destroyed or rejected A sample has been marked for destruction (damaged, rejected, etc.)
sample.shipped_lab Sample shipped to lab A sample has been shipped to the processing lab

Webhook Payloads

sample.received

{
  "event": "sample.received",
  "timestamp": "2026-04-03T15:00:00.000Z",
  "data": {
    "kit_id": "KIT-10001",
    "sample_id": "SMP-20001"
  }
}

sample_id is only included when available. kit_id is always present.

sample.discarded

{
  "event": "sample.discarded",
  "timestamp": "2026-04-03T15:05:00.000Z",
  "data": {
    "kit_id": "KIT-10002",
    "reason": "Damaged tube"
  }
}

sample.shipped_lab

{
  "event": "sample.shipped_lab",
  "timestamp": "2026-04-03T16:30:00.000Z",
  "data": {
    "kit_id": "KIT-10001",
    "sample_id": "SMP-20001"
  }
}
🛈
Webhook Security All webhooks are signed with HMAC-SHA256. Verify using the X-Webhook-Signature or X-Signature header. See the Webhook docs for verification examples.

Sample Statuses

StatusDescription
validReceived and accepted, awaiting storage assignment
holdOn hold for manual review
priorityMarked for priority handling
storedStored in a warehouse location, available for shipment
allocatedAllocated to a sample shipment, pending pick/pack
shippedShipped to the processing lab
destroyedSample was destroyed (damaged, rejected, etc.)
exceptionException during receiving (damaged, missing, unreadable)

Error Codes

HTTP StatusCodeDescription
401UNAUTHORIZEDMissing or invalid authorization token
403CUSTOMER_NOT_FOUNDCustomer account not found or inactive
404NOT_FOUNDSample or shipment not found
400BAD_REQUESTInvalid request (e.g., samples not in stored status)
500INTERNAL_ERRORServer error

Error Response Format

{
  "error": "Some kit IDs were not found",
  "not_found": ["INVALID001"]
}