> ## 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 Xquik support ticket with media API

> Open a private support ticket with a subject, message, screenshots, or videos. Save its ticket ID for replies, status updates, and downloads. Tickets are free.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-support-create-200">
      ```json theme={null}
      {
        "publicId": "tkt_a1b2c3d4e5f6a1b2c3d4e5f6",
        "attachments": []
      }
      ```
    </Tab>

    <Tab title="201" id="response-support-create-201">
      ```json theme={null}
      {
        "publicId": "tkt_a1b2c3d4e5f6a1b2c3d4e5f6",
        "attachments": []
      }
      ```
    </Tab>

    <Tab title="400" id="response-support-create-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid input. Check the request body."
      }
      ```
    </Tab>

    <Tab title="401" id="response-support-create-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required. Provide a valid API key or bearer token."
      }
      ```
    </Tab>

    <Tab title="409" id="response-support-create-409">
      ```json theme={null}
      {
        "error": "idempotency_key_conflict",
        "message": "Reuse this Idempotency-Key only with the original request."
      }
      ```
    </Tab>

    <Tab title="429" id="response-support-create-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>
  </Tabs>
</Panel>

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

## When to open a new ticket

Use this route to open a new conversation with support. Send JSON for text-only tickets and multipart data for attachments. Use reply only after the response provides a ticket ID.

<Callout icon="circle-check" color="#16a34a">
  **Free.** This endpoint does not consume credits.
</Callout>

Use JSON for text-only tickets. Use `multipart/form-data` when attaching media.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://xquik.com/api/v1/support/tickets \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Idempotency-Key: replace-with-one-random-value" \
    -H "Content-Type: application/json" \
    -d '{
      "subject": "Cannot connect X account",
      "body": "I keep getting a connection error when trying to link my account."
    }' | jq
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/support/tickets", {
    method: "POST",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
      "Idempotency-Key": crypto.randomUUID(),
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      subject: "Cannot connect X account",
      body: "I keep getting a connection error when trying to link my account.",
    }),
  });
  const data = await response.json();
  ```

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

  response = requests.post(
      "https://xquik.com/api/v1/support/tickets",
      headers={
          "x-api-key": "xq_YOUR_KEY_HERE",
          "Idempotency-Key": "replace-with-one-random-value",
      },
      json={
          "subject": "Cannot connect X account",
          "body": "I keep getting a connection error when trying to link my account.",
      },
  )
  data = response.json()
  ```

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

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

  func main() {
      body, _ := json.Marshal(map[string]interface{}{
          "subject": "Cannot connect X account",
          "body":    "I keep getting a connection error when trying to link my account.",
      })

      req, err := http.NewRequest("POST", "https://xquik.com/api/v1/support/tickets", bytes.NewReader(body))
      if err != nil {
          panic(err)
      }
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")
      req.Header.Set("Idempotency-Key", "replace-with-one-random-value")
      req.Header.Set("Content-Type", "application/json")

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

      var data map[string]interface{}
      if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
          panic(err)
      }
      fmt.Println(data)
  }
  ```
</CodeGroup>

| Support ticket receipt column | Request or response source | Handoff rule |
| - | - | - |
| Idempotency key | Request header | Reuse it only for an identical retry. |
| Ticket subject | Request `subject` | State the affected tweet, follower, or account workflow. |
| Initial message | Request `body` | Include the failure and attempted fix. |
| Ticket ID | Response `publicId` | Use this ID for status and reply requests. |
| Attachment ID | `attachments[].publicId` | Store the attachment ID with the ticket. |
| Attachment state | `attachments[].status` | Continue only when the attachment is `ready`. |
| Safe replay | `Idempotency-Replayed: true` | Reuse the original ticket response. |

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. Session cookie authentication is also supported. Generate a key from the [dashboard](https://xquik.com/dashboard).
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Use `application/json` for text only. Use `multipart/form-data` for media.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Generate one random value for this submission. Reuse it only when retrying identical text and attachments. A replay returns the original ticket with `Idempotency-Replayed: true`.
</ParamField>

## Body

<ParamField body="subject" type="string" required>
  Ticket subject. 1-500 characters.
</ParamField>

<ParamField body="body" type="string" required>
  Initial message. 1-10,000 characters.
</ParamField>

<ParamField body="attachments" type="file[]">
  Up to 4 JPEG, PNG, GIF, WebP, MP4, MOV, or WebM files. Images can be 10 MB each. Videos can be 25 MB each. Combined media can be 30 MB.
</ParamField>

For a media-only ticket, omit `body` and include at least 1 attachment.

```bash cURL With Media theme={null}
curl -X POST https://xquik.com/api/v1/support/tickets \
  -H "x-api-key: xq_YOUR_KEY_HERE" \
  -H "Idempotency-Key: replace-with-one-random-value" \
  -F "subject=Video upload problem" \
  -F "body=The attached recording shows the failure." \
  -F "attachments=@screen.png" \
  -F "attachments=@recording.mp4" | jq
```

## Response

### 201 Created

<ResponseField name="publicId" type="string">
  Unique ticket public ID.
</ResponseField>

<ResponseField name="attachments" type="object[]">
  Created media receipts.
</ResponseField>

<ResponseField name="attachments[].publicId" type="string">
  Private attachment public ID.
</ResponseField>

<ResponseField name="attachments[].status" type="string">
  Upload status: `ready` or `failed`.
</ResponseField>

```json theme={null}
{
  "publicId": "tkt_a1b2c3d4e5f6a1b2c3d4e5f6",
  "attachments": [
    {
      "publicId": "att_a1b2c3d4e5f6a1b2c3d4e5f6",
      "status": "ready"
    }
  ]
}
```

### 200 Replayed

Returns the original response after a safe retry. The `Idempotency-Replayed` response header is `true`.

### 400 Invalid input

```json theme={null}
{ "error": "invalid_input", "message": "Invalid input. Check the request body." }
```

Missing or invalid `subject` or `body` field.

### 401 Unauthenticated

```json theme={null}
{
  "error": "unauthenticated",
  "message": "Authentication required. Provide a valid API key or bearer token."
}
```

Missing or invalid API key.

### 409 Conflict

The `Idempotency-Key` already belongs to different text or attachments. Generate a new key for the changed request.

### 429 Rate limited

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Try again later.",
  "retryAfter": 60
}
```

Wait for the `Retry-After` value before opening another ticket.

<Note>
  **Next steps.** [Support Media](/api-reference/support/media) explains privacy, formats, limits, status handling, and downloads.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.