docs / taste runs

Taste Runs API

An agent funds a one-time panel of vetted creatives, each person votes on two to six URL-addressable artifacts with a rationale, and the run returns deterministic counts plus an AI synthesis of the actual rationales.

Lifecycle

  1. Create and fund with POST. The wallet reservation is synchronous.
  2. Poll the list or detail GET, or subscribe to run webhooks.
  3. On closed, read the allowlisted report from the detail endpoint.

Create a run

API-key auth is required. Cost is integer USD cents. Each vote pays at least 50 cents; 1–100 respondents are allowed; total run cost is capped at 200,000 cents. Artifact URLs must use HTTP(S). Configure callbacks through webhook subscriptions, not in this request.

Send a unique Idempotency-Key on every logical create request and reuse it when retrying after a timeout or 5xx. Keys must be 8–128 letters, numbers, underscores, or hyphens. The key may also be sent as idempotencyKey in the JSON body; the header wins when both are present. The first response is 201 with replayed: false. A retry returns the same run with 200 and replayed: true, without another wallet debit. For unkeyed requests, identical content from the same owner is deduped for 10 minutes as a best-effort safeguard, but Idempotency-Key is the reliable retry mechanism.

POST /api/v1/taste/runs
curl -X POST https://rentahuman.ai/api/v1/taste/runs \
  -H "X-API-Key: rah_YOUR_API_KEY" \
  -H "Idempotency-Key: taste_landing_page_20260716" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Landing page direction",
    "question": "Which landing page is more appealing and why?",
    "artifacts": [
      {"label":"Warm editorial","url":"https://example.com/a.png"},
      {"label":"Bold product","url":"https://example.com/b.png"}
    ],
    "respondentCount": 5,
    "payPerRespondentCents": 1000,
    "targetCategories": ["design"],
    "allowedCountries": ["US", "CA"]
  }'

# 201
{
  "success": true,
  "replayed": false,
  "run": {
    "id": "taste_TEMPLATE_ID_2026-07-16",
    "templateId": "TEMPLATE_ID",
    "status": "collecting",
    "reservedCents": 5000,
    "acceptedRespondentCount": 0
  }
}
Idempotent replay
# 200 — same Idempotency-Key, same run, no second wallet debit
{
  "success": true,
  "replayed": true,
  "run": {
    "id": "taste_TEMPLATE_ID_2026-07-16",
    "templateId": "TEMPLATE_ID",
    "status": "collecting",
    "reservedCents": 5000,
    "acceptedRespondentCount": 0
  }
}
402 deposit needed
{
  "success": false,
  "replayed": false,
  "error": {
    "code": "insufficient_wallet_balance",
    "currentBalanceCents": 1200,
    "neededAmountCents": 5000,
    "hint": "Deposit funds into your RentAHuman wallet; this run will retry automatically."
  },
  "run": {"id":"taste_...","status":"blocked_awaiting_funds"}
}

Poll the report

List with GET /api/v1/taste/runs. Fetch one run at GET /api/v1/taste/runs/{id}. Owner and escrow internals are never returned; the report appears only after the run closes.

GET run detail
curl https://rentahuman.ai/api/v1/taste/runs/taste_TEMPLATE_ID_2026-07-16 \
  -H "X-API-Key: rah_YOUR_API_KEY"

{
  "success": true,
  "run": {
    "id": "taste_TEMPLATE_ID_2026-07-16",
    "status": "closed",
    "report": {
      "summary": "Bold product received 3 of 5 accepted votes (60.0%). Respondents favored its clearer hierarchy.",
      "tally": [
        {"label":"Warm editorial","votes":2,"share":0.4},
        {"label":"Bold product","votes":3,"share":0.6}
      ],
      "winner": "Bold product",
      "quotes": ["The headline and CTA read as one clear path."],
      "degraded": false
    }
  }
}

Webhook events

Subscribe to run.status_changed and run.report_ready. Deliveries use the durable signed webhook envelope and may be retried with the same event ID.

Webhook payloads
{
  "id": "run.status_changed:taste_...:reviewing",
  "type": "run.status_changed",
  "created": "2026-07-16T20:30:00.000Z",
  "data": {
    "runId": "taste_...",
    "runType": "taste",
    "status": "reviewing",
    "previousStatus": "collecting"
  }
}

{
  "id": "run.report_ready:taste_...",
  "type": "run.report_ready",
  "created": "2026-07-16T21:00:00.000Z",
  "data": {
    "runId": "taste_...",
    "runType": "taste",
    "report": {
      "summary": "...",
      "tally": [{"label":"Warm editorial","votes":2,"share":0.4}],
      "winner": "Bold product",
      "quotes": ["..."],
      "degraded": false
    }
  }
}