---
title: "Create a query"
method: POST
path: "/requestor/queries"
tags: ["Queries"]
---

# Create a query

`POST /requestor/queries`

## Request

- Base URL: `https://www.getabrain.ai/api/v1`
- URL: `https://www.getabrain.ai/api/v1/requestor/queries`
- Auth: one of:
  - API key in header `X-API-Key` and API key in header `X-API-Secret`
  - HTTP bearer

Escrows (bid + bonus) x required_responses plus the 15% platform fee and dispatches to matched human workers. With a test-mode key nothing is charged and up to 10 synthetic responses (marked simulated: true, max 50/day per account) are injected. Rate limits by account tier: trial (no completed deposit yet) 10 creations/min and 100/day; standard 60/min; high-volume 300/min. GET /requestor/usage reports your tier and limits.

## Request body

- object
  - `type` 'text' | 'multiple_choice' | 'rating_scale' | 'image_comparison' | 'ranking' | 'yes_no' | 'sentiment' | 'image_selection' | 'free_form_text' | 'video_review' | 'audio_review' | 'image_analysis' | 'ab_test' | 'voice_capture' | 'video_capture' | 'photo_capture', required
  - `title` string, required
  - `description` string
  - `content_data` union, required
    - TextContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `min_words` integer
      - `max_words` integer
      - `required_fields` string[]
    - MultipleChoiceContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `options` object[], required
        - `id` string, required
        - `text` string, required
        - `image_url` string
      - `allow_multiple` boolean
      - `min_selections` integer
      - `max_selections` integer
    - RatingScaleContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `scale_type` '1-5' | '1-10' | '0-100' | 'stars', required
      - `scale_min` number, required
      - `scale_max` number, required
      - `scale_labels` object
        - `min_label` string
        - `mid_label` string
        - `max_label` string
      - `criteria` string[]
      - `media_url` string: Optional HTTP(S) reference URL, rendered as a plain link
      - `media_image_url` string: Optional image to display above the rating question
      - `media_video_url` string: Optional YouTube URL to embed above the rating question
      - `media_audio_url` string: Optional audio URL to embed above the rating question
    - ImageComparisonContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `images` object[], required
        - `id` string, required
        - `url` string, required
        - `label` string
        - `description` string
      - `comparison_type` 'preference' | 'quality' | 'relevance' | 'custom', required
      - `require_reasoning` boolean
    - RankingContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `items` object[], required
        - `id` string, required
        - `text` string, required
        - `image_url` string
        - `description` string
      - `max_items` integer, required
      - `require_all` boolean
    - YesNoContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `require_explanation` boolean
      - `min_explanation_words` integer
    - SentimentContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `subject` string, required
      - `sentiment_options` string[], required
      - `require_reasoning` boolean
    - ImageSelectionContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `images` object[], required
        - `id` string, required
        - `url` string, required
        - `caption` string
      - `min_selections` integer, required
      - `max_selections` integer, required
      - `selection_criteria` string, required
    - FreeFormTextContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `prompt` string, required
      - `min_characters` integer
      - `max_characters` integer
      - `format_guidelines` string
    - VideoReviewContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `video_url` string, required: YouTube URL
      - `video_duration_seconds` integer, required
      - `review_aspects` string[], required
      - `min_watch_time_seconds` integer
    - AudioReviewContent
      - `question` string, required
      - `instructions` string
      - `context` string
      - `audio_url` string, required
      - `audio_duration_seconds` integer, required
      - `review_aspects` string[], required
      - `transcription_required` boolean
    - ImageAnalysisContent
      - `question` string, required
      - `image_url` string, required: HTTP(S) image URL
    - AbTestContent
      - `question` string, required
      - `variant_a` object, required
        - `description` string, required
        - `image_url` string
        - `url` string
      - `variant_b` object, required
        - `description` string, required
        - `image_url` string
        - `url` string
    - VoiceCaptureContent
      - `question` string
      - `instructions` string
      - `context` string
      - `prompt` string, required
      - `max_duration_seconds` integer
    - VideoCaptureContent
      - `question` string
      - `instructions` string
      - `context` string
      - `prompt` string, required
      - `max_duration_seconds` integer
    - PhotoCaptureContent
      - `question` string
      - `instructions` string
      - `context` string
      - `prompt` string, required
  - `required_responses` integer, required
  - `bid_amount_cents` integer, required: Payment per response in cents. The minimum is effort-priced PER TYPE (absolute floor 5; e.g. yes_no/multiple_choice/sentiment 5, image_comparison 8, text/ranking/image_analysis 12, free_form_text/video_capture 30; video_review/audio_review scale with clip length). Call GET /requestor/suggested-bid?type=<type> for min_bid_cents + suggested_bid_cents; a bid under the floor is rejected with 400. A 15% platform fee is added on top of bid x required_responses.
  - `bonus_amount_cents` integer
  - `min_worker_quality` number
  - `required_languages` string[]
  - `required_location_countries` string[]
  - `required_skills` string[]
  - `excluded_worker_ids` string[]
  - `expires_in_hours` integer: Hours until the query auto-expires (default 72, max 168). Unfilled response slots are refunded to your balance on expiry.
  - `webhook_url` string, uri: Per-query override: public https URL to receive signed response.submitted / query.completed events

## Response `201`

Query created (status "active", or "moderation_hold" with an explanatory "message" field if the content was flagged for review — the bid is escrowed either way). test_mode is true for queries created with a test-mode key.

- object
  - `id` string, uuid
  - `type` string
  - `title` string
  - `description` string
  - `required_responses` integer
  - `completed_responses` integer
  - `bid_amount_cents` integer
  - `bonus_amount_cents` integer
  - `total_cost_cents` integer
  - `status` 'pending' | 'active' | 'moderation_hold' | 'completed' | 'cancelled' | 'failed' | 'expired' | 'rejected'
  - `created_at` string, date-time
  - `expires_at` string, date-time, nullable
  - `test_mode` boolean
  - `message` string

## Other responses

- `400`: Request failed validation
- `401`: Missing or invalid authentication
- `402`: Insufficient prepaid balance to fund the query
- `429`: Too many requests for your account tier (see GET /requestor/usage for your limits). Wait Retry-After seconds and retry.

---

[API](https://skmtc.dev/getabrain/apis/getabrain-ai-api.md) · [All operations](https://skmtc.dev/getabrain/apis/getabrain-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getabrain/apis/getabrain-ai-api/revisions/e9da90b7b72c?raw)
