> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create draw

> Execute a giveaway draw on a tweet to select random winners

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<Callout icon="coins" color="#5c3327">
  **Metered draw execution** · source lookup, replies, optional retweeters, and optional follow checks consume credits
</Callout>

<Note>
  Remaining credits cap how many replies and retweeters Xquik can inspect before filters run. `totalEntries` and `validEntries` describe that inspected candidate set, not necessarily every reply on the source tweet.
</Note>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://xquik.com/api/v1/draws \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Content-Type: application/json" \
    -d '{
      "tweetUrl": "https://x.com/xquik/status/1893456789012345678",
      "winnerCount": 3,
      "backupCount": 2,
      "mustRetweet": true,
      "filterMinFollowers": 10,
      "requiredKeywords": ["giveaway"]
    }' | jq
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/draws", {
    method: "POST",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      tweetUrl: "https://x.com/xquik/status/1893456789012345678",
      winnerCount: 3,
      backupCount: 2,
      mustRetweet: true,
      filterMinFollowers: 10,
      requiredKeywords: ["giveaway"],
    }),
  });
  const data = await response.json();
  console.log(data);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://xquik.com/api/v1/draws",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
      json={
          "tweetUrl": "https://x.com/xquik/status/1893456789012345678",
          "winnerCount": 3,
          "backupCount": 2,
          "mustRetweet": True,
          "filterMinFollowers": 10,
          "requiredKeywords": ["giveaway"],
      },
  )
  data = response.json()
  print(data)
  ```

  ```go Go theme={null}
  package main

  import (
  	"bytes"
  	"encoding/json"
  	"fmt"
  	"io"
  	"log"
  	"net/http"
  )

  func main() {
  	payload := map[string]interface{}{
  		"tweetUrl":           "https://x.com/xquik/status/1893456789012345678",
  		"winnerCount":        3,
  		"backupCount":        2,
  		"mustRetweet":        true,
  		"filterMinFollowers": 10,
  		"requiredKeywords":   []string{"giveaway"},
  	}
  	body, err := json.Marshal(payload)
  	if err != nil {
  		log.Fatal(err)
  	}

  	req, err := http.NewRequest("POST", "https://xquik.com/api/v1/draws", bytes.NewReader(body))
  	if err != nil {
  		log.Fatal(err)
  	}
  	req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")
  	req.Header.Set("Content-Type", "application/json")

  	resp, err := http.DefaultClient.Do(req)
  	if err != nil {
  		log.Fatal(err)
  	}
  	defer resp.Body.Close()

  	respBody, err := io.ReadAll(resp.Body)
  	if err != nil {
  		log.Fatal(err)
  	}
  	fmt.Println(string(respBody))
  }
  ```
</CodeGroup>

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. Session cookie authentication is also supported.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

## Body

<ParamField body="tweetUrl" type="string" required>
  Full tweet URL to run the draw on. Accepts `x.com` and `twitter.com` formats (e.g. `https://x.com/user/status/1893456789012345678`).
</ParamField>

<ParamField body="winnerCount" type="number">
  Number of winners to draw. Defaults to `1` if omitted.
</ParamField>

<ParamField body="backupCount" type="number">
  Number of backup winners to draw. Backup winners are selected in case primary winners are disqualified.
</ParamField>

<ParamField body="uniqueAuthorsOnly" type="boolean">
  When `true`, each author can only win once regardless of how many replies they posted.
</ParamField>

<ParamField body="mustRetweet" type="boolean">
  When `true`, only entries from users who retweeted the original tweet are eligible.
</ParamField>

<ParamField body="mustFollowUsername" type="string">
  X username that entrants must follow to be eligible. The `@` prefix is stripped if included.
</ParamField>

<ParamField body="filterMinFollowers" type="number">
  Minimum follower count required for eligible entries.
</ParamField>

<ParamField body="filterAccountAgeDays" type="number">
  Minimum account age in days. Accounts younger than this are excluded.
</ParamField>

<ParamField body="filterLanguage" type="string">
  Filter entries by tweet language code (e.g. `en`, `tr`, `es`).
</ParamField>

<ParamField body="requiredKeywords" type="string[]">
  Array of keywords that must appear in the reply text. Entries missing any keyword are excluded.
</ParamField>

<ParamField body="requiredHashtags" type="string[]">
  Array of hashtags that must appear in the reply text. Include the `#` prefix.
</ParamField>

<ParamField body="requiredMentions" type="string[]">
  Array of usernames that must be mentioned in the reply text. Include the `@` prefix.
</ParamField>

## Response

<Tabs>
  <Tab title="201 Created">
    <ResponseField name="id" type="string">Draw public ID returned by Xquik.</ResponseField>
    <ResponseField name="tweetId" type="string">X tweet ID extracted from the URL.</ResponseField>
    <ResponseField name="totalEntries" type="number">Candidate entries inspected for this draw after the credit-derived cap. This may be lower than the source tweet's full reply count.</ResponseField>
    <ResponseField name="validEntries" type="number">Entries from the inspected candidate set that passed all filters.</ResponseField>

    <ResponseField name="winners" type="array">
      Selected winners and backup winners.

      <Expandable title="winner object">
        <ResponseField name="position" type="number">Winner position (1-indexed).</ResponseField>
        <ResponseField name="authorUsername" type="string">X username of the winner.</ResponseField>
        <ResponseField name="tweetId" type="string">Tweet ID of the winning reply.</ResponseField>
        <ResponseField name="isBackup" type="boolean">`true` if this is a backup winner.</ResponseField>
      </Expandable>
    </ResponseField>

    ```json theme={null}
    {
      "id": "f4bd00a2-7b4e-4e59-8e1b-72e2c9f12345",
      "tweetId": "1893456789012345678",
      "totalEntries": 847,
      "validEntries": 312,
      "winners": [
        {
          "position": 1,
          "authorUsername": "alice_web3",
          "tweetId": "1893456789012345700",
          "isBackup": false
        },
        {
          "position": 2,
          "authorUsername": "bob_dev",
          "tweetId": "1893456789012345701",
          "isBackup": false
        },
        {
          "position": 3,
          "authorUsername": "charlie_nft",
          "tweetId": "1893456789012345702",
          "isBackup": false
        },
        {
          "position": 4,
          "authorUsername": "diana_crypto",
          "tweetId": "1893456789012345703",
          "isBackup": true
        },
        {
          "position": 5,
          "authorUsername": "eve_trades",
          "tweetId": "1893456789012345704",
          "isBackup": true
        }
      ]
    }
    ```
  </Tab>

  <Tab title="400 Invalid Input">
    ```json theme={null}
    { "error": "invalid_input", "message": "Missing or malformed request body" }
    ```

    Missing or malformed request body. Ensure `tweetUrl` is a string.
  </Tab>

  <Tab title="400 Invalid Tweet URL">
    ```json theme={null}
    { "error": "invalid_tweet_url", "message": "Invalid tweet URL format" }
    ```

    The `tweetUrl` could not be parsed. Must be a valid `x.com` or `twitter.com` status URL.
  </Tab>

  <Tab title="401 Unauthenticated">
    ```json theme={null}
    { "error": "unauthenticated", "message": "Missing or invalid API key" }
    ```

    Missing or invalid API key / session cookie.
  </Tab>

  <Tab title="402 Subscription required">
    ```json theme={null}
    { "error": "no_subscription", "message": "No active subscription" }
    ```

    No active subscription, inactive subscription, no credits, or insufficient credits. Draws first check that the minimum draw cost is affordable. A later final deduction failure returns `insufficient_credits` and no draw result is persisted. Check your [credit balance](/api-reference/account/get).
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    { "error": "tweet_not_found", "message": "Tweet not found" }
    ```

    The target tweet does not exist, was deleted, or the ID is invalid.
  </Tab>

  <Tab title="424 X API Dependency Failed">
    ```json theme={null}
    {
      "error": {
        "type": "dependency_error",
        "code": "x_api_unavailable",
        "message": "X data source temporarily unavailable"
      }
    }
    ```

    Send `xquik-api-contract: 2026-04-29` to receive this status for dependency failures that return `502` by default.
  </Tab>

  <Tab title="429 Rate Limited">
    ```json theme={null}
    { "error": "rate_limit_exceeded", "message": "Too many requests. Try again later.", "retryAfter": 1 }
    ```

    Too many requests. Wait for the `Retry-After` header before retrying.
  </Tab>

  <Tab title="502 X API Unavailable">
    ```json theme={null}
    { "error": "x_api_unavailable", "message": "X data source temporarily unavailable" }
    ```

    The read service returned an error. Retry after a short delay.
  </Tab>
</Tabs>

<Note>
  **Next steps:** [Get Draw](/api-reference/draws/get) to retrieve full draw details including tweet metadata, [Export Draw](/api-reference/draws/export) to download results as CSV/XLSX/Markdown, or [List Draws](/api-reference/draws/list) to see your draw history.
</Note>
