curl --request POST \
--url https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit \
--header 'Authorization: Bearer <token>'import requests
url = "https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"confirmed_at": "2026-02-15T14:30:00Z",
"experiment_id": "019462a4-b1c2-7def-8901-23456789abcd",
"previous_status": "draft",
"status": "draft",
"stripe_invoice_url": "https://invoice.stripe.com/i/acct_1234/test_5678"
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}{
"error": "Cannot submit draft experiment: Stripe quote creation failed.",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd",
"error_kind": "customer_quote_cap",
"hint": "Stripe rejected the quote: this organization's customer has reached the draft-quote cap. Contact admin to cancel stale test-mode quotes."
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}Submit experiment
Submits a draft experiment for review. Advances from Draft to
WaitingForConfirmation by finalizing the Stripe quote. To accept an
already-submitted quote, use POST /experiments/{id}/quote/confirm.
curl --request POST \
--url https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit \
--header 'Authorization: Bearer <token>'import requests
url = "https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://devs.adaptyvbio.com/api/v1/experiments/{experiment_id}/submit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"confirmed_at": "2026-02-15T14:30:00Z",
"experiment_id": "019462a4-b1c2-7def-8901-23456789abcd",
"previous_status": "draft",
"status": "draft",
"stripe_invoice_url": "https://invoice.stripe.com/i/acct_1234/test_5678"
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}{
"error": "Cannot submit draft experiment: Stripe quote creation failed.",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd",
"error_kind": "customer_quote_cap",
"hint": "Stripe rejected the quote: this organization's customer has reached the draft-quote cap. Contact admin to cancel stale test-mode quotes."
}{
"error": "experiment not found",
"request_id": "req_019462a4-b1c2-7def-8901-23456789abcd"
}Authorizations
Biscuit-based bearer token. Obtain tokens from the Adaptyv Portal or via the /tokens endpoint. Tokens encode organization membership and role-based capabilities; the API verifies the token's cryptographic signature and authorization claims before processing requests. Use /tokens/attenuate to create restricted tokens for delegation.
Path Parameters
Experiment identifier
Response
Experiment submitted for review
Confirmation response returned after a status transition via POST /confirm.
The confirm endpoint automatically advances the experiment through its lifecycle based on the current status. This response reports both the previous and new status so callers can verify what transition occurred.
RFC3339 timestamp when confirmation completed
"2026-02-15T14:30:00Z"
Experiment identifier
"019462a4-b1c2-7def-8901-23456789abcd"
Status before the transition
draft, waiting_for_confirmation, canceled, waiting_for_materials, in_production, quote_sent, in_queue, data_analysis, in_review, done Status after the transition
draft, waiting_for_confirmation, canceled, waiting_for_materials, in_production, quote_sent, in_queue, data_analysis, in_review, done Hosted invoice URL from Stripe (available after WaitingForConfirmation → WaitingForMaterials)
"https://invoice.stripe.com/i/acct_1234/test_5678"
Was this page helpful?