Reference for every surface Crawltic exposes: REST and GraphQL endpoints, typed SDKs, the CLI, the MCP server for AI agents, signed webhooks, and declarative decision rules.
Install the CLI, authenticate once, and create an experiment. Every step below is also a single REST call, so you can run the same flow from CI.
Homebrew, npm, pip, or a static binary for Linux and Windows.
brew install crawltic/tap/crawlticOpens a browser once and stores a scoped key in your OS keychain. In CI, set CRAWLTIC_API_KEY.
crawltic loginDefine variants and the metric that decides the winner, then request an assignment for any user key.
crawltic experiments create ...Base URL https://api.crawltic.com/v1. Authenticate with Authorization: Bearer <key>. All bodies are JSON, all timestamps are RFC 3339, and every write accepts an Idempotency-Key header.
| Method | Path | Description | p50 |
|---|---|---|---|
| POST | /experiments | Create an experiment with variants, metric, and allocation | 18ms |
| GET | /experiments | List experiments, filterable by status and tag | 9ms |
| GET | /experiments/{id} | Fetch configuration and current status | 6ms |
| PATCH | /experiments/{id} | Update allocation, pause, or resume | 14ms |
| DELETE | /experiments/{id} | Archive an experiment and freeze its results | 12ms |
| GET | /assign | Deterministic, sticky variant assignment for a user key | 3.8ms |
| POST | /events | Log a conversion or any custom metric value | 5.1ms |
| POST | /events/batch | Up to 5,000 events per request, gzip accepted | 22ms |
| GET | /experiments/{id}/results | Posteriors, p-values, lift, and the current decision | 11.6ms |
| POST | /experiments/{id}/ship | Promote a variant, optionally as a staged ramp | 31ms |
| POST | /webhooks | Subscribe an endpoint to experiment lifecycle events | 16ms |
| DELETE | /webhooks/{id} | Remove a subscription and rotate its secret | 10ms |
curl https://api.crawltic.com/v1/experiments \ -H "Authorization: Bearer $CRAWLTIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "checkout-button", "metric": "revenue_per_visitor", "variants": ["control", "v2"], "traffic_allocation": 1.0 }' # then assign a user curl "https://api.crawltic.com/v1/assign?experiment=checkout-button&user=usr_8821" \ -H "Authorization: Bearer $CRAWLTIC_API_KEY"
import { Crawltic } from "@crawltic/sdk"; const ct = new Crawltic({ apiKey: process.env.CRAWLTIC_API_KEY }); const exp = await ct.experiments.create({ name: "checkout-button", metric: "revenue_per_visitor", variants: ["control", "v2"], trafficAllocation: 1.0, }); const { variant } = await ct.assign(exp.id, { user: "usr_8821" }); // variant === "v2", sticky for this user
from crawltic import Crawltic ct = Crawltic() # reads CRAWLTIC_API_KEY exp = ct.experiments.create( name="checkout-button", metric="revenue_per_visitor", variants=["control", "v2"], traffic_allocation=1.0, ) variant = ct.assign(exp.id, user="usr_8821").variant # "v2", sticky for this user
client := crawltic.NewClient(os.Getenv("CRAWLTIC_API_KEY")) exp, err := client.Experiments.Create(ctx, &crawltic.ExperimentParams{ Name: "checkout-button", Metric: "revenue_per_visitor", Variants: []string{"control", "v2"}, TrafficAllocation: 1.0, }) if err != nil { log.Fatal(err) } a, _ := client.Assign(ctx, exp.ID, "usr_8821") // a.Variant == "v2"
curl -X POST https://api.crawltic.com/v1/events \ -H "Authorization: Bearer $CRAWLTIC_API_KEY" \ -d '{"experiment":"checkout-button","user":"usr_8821","metric":"order_value","value":84.20}' curl https://api.crawltic.com/v1/experiments/checkout-button/results \ -H "Authorization: Bearer $CRAWLTIC_API_KEY" # { "v2": { "mean": 48.80, "prob_to_beat": 0.962 }, "decision": "ship" }
await ct.track({ experiment: "checkout-button", user: "usr_8821", metric: "order_value", value: 84.2, }); const r = await ct.results("checkout-button"); console.log(r.variants.v2.probToBeat, r.decision); // 0.962 "ship"
ct.track( experiment="checkout-button", user="usr_8821", metric="order_value", value=84.20, ) r = ct.results("checkout-button") print(r.variants["v2"].prob_to_beat, r.decision) # 0.962 ship
_ = client.Track(ctx, crawltic.Event{ Experiment: "checkout-button", User: "usr_8821", Metric: "order_value", Value: 84.20, }) r, _ := client.Results(ctx, "checkout-button") fmt.Println(r.Variants["v2"].ProbToBeat, r.Decision) // 0.962 ship
Rate limits: 5,000 requests per minute per key, returned in X-RateLimit-Remaining. Assignment calls are served from the edge and do not count against the limit.
Every REST resource is mirrored at /v1/graphql. Subscriptions stream result updates over WebSocket the moment new evidence lands, so dashboards never poll.
query Results { experiment(name: "checkout-button") { status variants { key mean n probToBeat } decision { action confidence } } } subscription Live { experimentUpdated(name: "checkout-button") { variant mean n probToBeat } }
SDKs sync experiment config in the background and bucket users in-process, so assignment never waits on the network. Events are batched and flushed on an interval or on shutdown.
npm i @crawltic/sdkpip install crawlticgo get crawltic.com/gogem install crawltic.package(url: "crawltic/swift")implementation("com.crawltic:sdk")Every command maps 1:1 to an API endpoint and supports --format json, so experiment logic drops straight into CI pipelines, cron jobs, and release scripts.
crawltic loginAuthenticate and store a scoped keycrawltic experiments createDefine variants, metric, allocationcrawltic assignResolve a variant for a user keycrawltic trackSend an event or metric valuecrawltic results --watchStream posteriors to the terminalcrawltic quota setConfigure decision thresholdscrawltic ship --rampPromote a winner in stagescrawltic rollbackRevert to control instantlyInstall with brew, npm i -g @crawltic/cli, or a static binary. Exit codes are stable, so crawltic results --fail-under 0.95 can gate a deploy.
Add Crawltic to Claude, Cursor, or any MCP client, and your agent can create, monitor, and ship experiments in plain language, with the same permissions as the key you give it.
{
"mcpServers": {
"crawltic": {
"command": "npx",
"args": ["-y", "@crawltic/mcp-server"],
"env": {
"CRAWLTIC_API_KEY": "sk_live_..."
}
}
}
}
create_experimentassign_variantlog_metricget_resultsship_winnerpause_experimentset_decision_rules
Every lifecycle event is signed with HMAC-SHA256 in the Crawltic-Signature header. Non-2xx responses are retried with exponential backoff for up to 24 hours, and every attempt is visible in the delivery log.
{
"type": "experiment.shipped",
"experiment": "checkout-button",
"variant": "v2",
"lift": 0.184,
"confidence": 0.962
}
Commit a crawltic.yaml next to your code. The engine re-evaluates every minute and ships, pauses, or rolls back once confidence, lift, and sample quotas all clear.
# crawltic.yaml experiment: checkout-button metric: epc decision: auto_ship: min_lift: 0.10 confidence: 0.95 quotas: min_visitors_per_variant: 1000 min_conversions: 100 guardrails: - metric: p95_latency_ms max_regression: 0.05 - metric: refund_rate max_regression: 0.02 on_breach: rollback ramp: [10, 50, 100]
Evaluated every 60s · ships the moment min_conversions clears
Grab a key, paste the quickstart, and watch results stream in within minutes.