> ## 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.

# Update banner

> Upload a new profile banner for one of your connected X accounts

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

<Callout icon="coins" color="#5c3327">
  **10 credits per call** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH https://xquik.com/api/v1/x/profile/banner \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -F "account=myxaccount" \
    -F "file=@banner.png" | jq
  ```

  ```javascript Node.js theme={null}
  const fs = require("fs");
  const FormData = require("form-data");

  const form = new FormData();
  form.append("account", "myxaccount");
  form.append("file", fs.createReadStream("banner.png"));

  const response = await fetch("https://xquik.com/api/v1/x/profile/banner", {
    method: "PATCH",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
    },
    body: form,
  });
  const data = await response.json();
  ```

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

  with open("banner.png", "rb") as f:
      response = requests.patch(
          "https://xquik.com/api/v1/x/profile/banner",
          headers={"x-api-key": "xq_YOUR_KEY_HERE"},
          files={"file": ("banner.png", f, "image/png")},
          data={"account": "myxaccount"},
      )
  data = response.json()
  ```

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

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io"
      "mime/multipart"
      "net/http"
      "os"
  )

  func main() {
      var buf bytes.Buffer
      writer := multipart.NewWriter(&buf)
      writer.WriteField("account", "myxaccount")

      file, err := os.Open("banner.png")
      if err != nil {
          panic(err)
      }
      defer file.Close()

      part, err := writer.CreateFormFile("file", "banner.png")
      if err != nil {
          panic(err)
      }
      io.Copy(part, file)
      writer.Close()

      req, err := http.NewRequest("PATCH", "https://xquik.com/api/v1/x/profile/banner", &buf)
      if err != nil {
          panic(err)
      }
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")
      req.Header.Set("Content-Type", writer.FormDataContentType())

      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>

<CodeGroup>
  ```bash URL Upload theme={null}
  curl -X PATCH https://xquik.com/api/v1/x/profile/banner \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Content-Type: application/json" \
    -d '{
      "account": "myxaccount",
      "url": "https://example.com/banner.png"
    }' | jq
  ```
</CodeGroup>

## 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 `multipart/form-data` for file uploads or `application/json` for URL uploads. Most HTTP clients set the multipart boundary automatically.
</ParamField>

## Body

<ParamField body="account" type="string" required>
  X username or account ID of your connected account to act as.
</ParamField>

<ParamField body="file" type="binary">
  Multipart upload file. Required unless `url` is provided. Accepted formats: JPEG, PNG. Maximum file size: 2 MB.
</ParamField>

<ParamField body="url" type="string">
  JSON upload URL. Required unless `file` is provided. Must be an HTTPS URL that Xquik can fetch directly.
</ParamField>

## Response

<Tabs>
  <Tab title="200 OK">
    <ResponseField name="success" type="boolean">Always `true` on success.</ResponseField>

    ```json theme={null}
    {
      "success": true
    }
    ```
  </Tab>

  <Tab title="400 Invalid Input">
    ```json theme={null}
    { "error": "invalid_input", "message": "Invalid file format or size exceeded" }
    ```

    The file is not a supported format (JPEG, PNG) or exceeds the 2 MB limit.
  </Tab>

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

    Missing or invalid API key.
  </Tab>

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

    An active subscription is required. Subscribe from the [dashboard](https://xquik.com/subscription).
  </Tab>

  <Tab title="402 Insufficient Credits">
    ```json theme={null}
    { "error": "insufficient_credits", "message": "Insufficient credits" }
    ```

    Insufficient credits for this operation. Top up your credit balance from the [dashboard](https://xquik.com/dashboard).
  </Tab>

  <Tab title="403 Account Needs Reauth">
    ```json theme={null}
    { "error": "account_needs_reauth" }
    ```

    The connected X account failed a recent login attempt and needs to be reconnected. Reconnect it from the [dashboard](https://xquik.com/dashboard).
  </Tab>

  <Tab title="403 Account Restricted">
    ```json theme={null}
    { "error": "account_restricted" }
    ```

    The connected X account is locked, suspended, recovering, or temporarily restricted. Resolve the restriction on X before retrying.
  </Tab>

  <Tab title="404 Account Not Found">
    ```json theme={null}
    { "error": "account_not_found", "message": "X account not found. Connect it first at /dashboard/account?tab=x-accounts." }
    ```

    The specified `account` is not connected to your Xquik account. Connect it from the [dashboard](https://xquik.com/dashboard).
  </Tab>

  <Tab title="422 Write Rejected">
    ```json theme={null}
    { "error": "x_content_too_long", "message": "..." }
    ```

    X rejected the write or the media URL could not be downloaded. Possible codes: `x_content_too_long`, `x_duplicate_action`, `x_account_suspended`, `x_account_protected`, `x_target_not_found`, `x_account_feature_required`, `x_rejected`, `media_download_failed` (URL fetch path only - body.url not HTTPS, resolves to private IP, file too large, origin error, or timeout). See [error handling](/guides/error-handling) for details.
  </Tab>

  <Tab title="429 Rate Limited">
    ```json theme={null}
    { "error": "rate_limit_exceeded", "retryAfter": 60 }
    ```

    The request hit an Xquik tier limit, or X throttled the banner update. Possible codes: `rate_limit_exceeded`, `x_rate_limited`, or `x_daily_limit`. Respect the `Retry-After` header when present.
  </Tab>

  <Tab title="503 Transient Error">
    ```json theme={null}
    { "error": "x_transient_error", "message": "..." }
    ```

    A transient write service issue occurred. Safe to retry with exponential backoff.
  </Tab>

  <Tab title="500 Write Failed">
    ```json theme={null}
    { "error": "x_write_failed", "message": "Failed to complete the action" }
    ```

    The write action failed. Retry after a short delay.
  </Tab>
</Tabs>

<Note>
  **Related:** [Update Avatar](/api-reference/x-write/update-avatar) to change the profile picture, or [Update Profile](/api-reference/x-write/update-profile) to update name, bio, and other text fields.
</Note>
