BuildAPI reference
API reference
Base URL: https://cloud.qbrix.io
This reference covers the endpoints you call from your application to run adaptive optimization: pools, experiments, selection and feedback, feature gates, and policies. Account, workspace, and billing management live in the console, not the API.
Prefer a typed client? Use an official SDK instead of raw HTTP — see the Python SDK and JavaScript / TypeScript SDK.
The curl examples below assume these environment variables:
export QBRIX_URL="https://cloud.qbrix.io"
export QBRIX_API_KEY="your-api-key"Authentication
All requests authenticate with an API key. Create and manage keys under Settings → API Keys in the console, then pass the key in the X-API-Key header:
curl $QBRIX_URL/api/v1/pools \
-H "X-API-Key: $QBRIX_API_KEY"Keys inherit the role of the workspace member that created them, which determines the operations they can perform. Keep keys secret and rotate them from the console if one is exposed.
Pools
/api/v1/poolsCreate a new pool with armspool = client.pool.create(
name="my-pool",
arms=[
{"name": "variant-a"},
{"name": "variant-b"},
{"name": "variant-c"},
],
)curl -X POST $QBRIX_URL/api/v1/pools \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-pool",
"arms": [
{"name": "variant-a"},
{"name": "variant-b"},
{"name": "variant-c"}
]
}'/api/v1/poolsList all pools (paginated)page = client.pool.list(limit=100, offset=0)
for pool in page.items:
print(pool.name)curl $QBRIX_URL/api/v1/pools \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/pools/{id}Get pool by IDpool = client.pool.get("<pool-id>")curl $QBRIX_URL/api/v1/pools/<pool-id> \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/pools/{id}Update pool/api/v1/pools/{id}Delete poolclient.pool.delete("<pool-id>")curl -X DELETE $QBRIX_URL/api/v1/pools/<pool-id> \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/pools/{id}/experimentsList experiments for poolexperiments = client.pool.list_experiments("<pool-id>")curl $QBRIX_URL/api/v1/pools/<pool-id>/experiments \
-H "X-API-Key: $QBRIX_API_KEY"Experiments
/api/v1/experimentsCreate a new experimentexperiment = client.experiment.create(
name="hero-test",
pool_id="<pool-id>",
policy="BetaTSPolicy",
)curl -X POST $QBRIX_URL/api/v1/experiments \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "hero-test",
"pool_id": "<pool-id>",
"policy": "BetaTSPolicy"
}'/api/v1/experimentsList experiments (paginated, filterable)page = client.experiment.list(limit=100, offset=0)
for exp in page.items:
print(f"{exp.name} ({exp.policy})")curl $QBRIX_URL/api/v1/experiments \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/experiments/{id}Get experiment by IDexperiment = client.experiment.get("<experiment-id>")curl $QBRIX_URL/api/v1/experiments/<experiment-id> \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/experiments/{id}Update experimentexperiment = client.experiment.update(
"<experiment-id>",
enabled=False,
)curl -X PATCH $QBRIX_URL/api/v1/experiments/<experiment-id> \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'/api/v1/experiments/{id}/resetReset learned params to configured policy_paramsResets the experiment's learned parameters back to its configured policy_params. Requires the experiment:write scope. The experiment must be paused first — a running experiment returns 409.
experiment = client.experiment.reset("<experiment-id>")curl -X POST $QBRIX_URL/api/v1/experiments/<experiment-id>/reset \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/experiments/{id}Delete experimentAgent (selection & feedback)
/api/v1/agent/selectSelect an armresult = client.agent.select(
experiment_id="<experiment-id>",
context={"id": "user-123"},
)curl -X POST $QBRIX_URL/api/v1/agent/select \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"experiment_id": "<experiment-id>",
"context": {"id": "user-123"}
}'For contextual policies, include the properties the experiment's schema declares:
from qbrix import Context
result = client.agent.select(
experiment_id="<experiment-id>",
context=Context(
id="user-123",
properties={"device": "mobile", "cart_value": 62.5},
metadata={"country": "US"},
),
)curl -X POST $QBRIX_URL/api/v1/agent/select \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"experiment_id": "<experiment-id>",
"context": {
"id": "user-123",
"properties": {"device": "mobile", "cart_value": 62.5},
"metadata": {"country": "US"}
}
}'/api/v1/agent/feedbackSubmit reward feedbackclient.agent.feedback(
request_id="<request-id>",
reward=1.0,
)curl -X POST $QBRIX_URL/api/v1/agent/feedback \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"request_id": "<request-id>",
"reward": 1.0
}'Both SDKs support a per-call timeout and a fallback arm on select() so a call fails open instead of hanging or raising when qbrix is unreachable — this is client-side behavior, not a request parameter these endpoints accept. See Handling outages.
Feature gates
/api/v1/gates/{experiment_id}Create a feature gategate = client.gate.create(
experiment_id="<experiment-id>",
enabled=True,
rollout_percentage=50.0,
)curl -X POST $QBRIX_URL/api/v1/gates/<experiment-id> \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"rollout_percentage": 50,
"rules": []
}'/api/v1/gates/{experiment_id}Get feature gate configgate = client.gate.get("<experiment-id>")curl $QBRIX_URL/api/v1/gates/<experiment-id> \
-H "X-API-Key: $QBRIX_API_KEY"/api/v1/gates/{experiment_id}Update part of a feature gateWrites the fields present in the body and leaves the rest of the gate as stored. An explicit null clears a field, and rules replaces the whole list — omit it to keep the stored rules, send [] to remove them.
gate = client.gate.update(
experiment_id="<experiment-id>",
rollout_percentage=50.0,
)curl -X PATCH $QBRIX_URL/api/v1/gates/<experiment-id> \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"rollout_percentage": 50}'/api/v1/gates/{experiment_id}Replace a feature gateReplaces the whole configuration: any field absent from the body is reset to its default. Use PATCH unless you mean to rewrite the gate wholesale.
curl -X PUT $QBRIX_URL/api/v1/gates/<experiment-id> \
-H "X-API-Key: $QBRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"rollout_percentage": 100,
"rules": [
{
"key": "country",
"operator": "in",
"value": ["US", "GB", "DE"],
"arm_id": "<arm-id>"
}
]
}'/api/v1/gates/{experiment_id}Delete feature gatePolicies
/api/v1/policiesList all available policiesReturns all policies with their configurable parameters. See the Policies page for detailed guidance.