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

# X API subscription checkout & billing portal

> Create a confirmed Xquik API subscription checkout or billing portal URL. Route new, active & payment-issue accounts without automatically charging the account.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-account-subscription-checkout-200">
      ```json theme={null}
      {
        "url": "https://xquik.com/billing/session",
        "status": "checkout_created",
        "message": "Billing session created"
      }
      ```
    </Tab>

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

    <Tab title="429" id="response-account-subscription-checkout-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>

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

<Info>
  Returns a checkout URL for new subscribers or a billing portal URL for existing subscribers.
</Info>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://xquik.com/api/v1/subscribe \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/subscribe", {
    method: "POST",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
    },
  });
  const data = await response.json();
  // Redirect user to data.url
  ```

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

  response = requests.post(
      "https://xquik.com/api/v1/subscribe",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
  )
  data = response.json()
  # Redirect user to data["url"]
  ```

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

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

  func main() {
      req, err := http.NewRequest("POST", "https://xquik.com/api/v1/subscribe", nil)
      if err != nil {
          panic(err)
      }
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")

      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>

## Create an X API subscription checkout

Call `POST /subscribe` after an authenticated user confirms a billing action.
The request creates a hosted URL. It never completes payment automatically.

Use this route for 3 account states:

| Account state | Response status | Returned destination |
| - | - | - |
| No active subscription | `checkout_created` | Hosted subscription checkout |
| Active or trialing subscription | `already_subscribed` | Billing portal for plan or payment management |
| Past-due or incomplete subscription | `payment_issue` | Billing portal for payment recovery |

Always route by `status`. Do not infer the destination from the URL hostname.
Use only the URL returned by the current response.

This endpoint does not quote current Twitter API pricing or X API pricing.
Review the [live Xquik pricing page](https://xquik.com/#pricing) before checkout.
The pricing page lists the current tiers, credits, and terms.

## Choose a subscription tier

Send `tier` only when the user selected a specific Xquik plan.

| Tier value | Checkout behavior |
| - | - |
| `starter` | Pre-select Starter. |
| `pro` | Pre-select Pro. |
| `business` | Pre-select Business. |
| Omitted | Let the user choose on the hosted checkout. |

The field pre-selects a tier. It does not activate that tier by itself.
Send only the documented enum values.

## Complete a safe billing handoff

1. Show the current plan and credit terms before confirmation.
2. Call this endpoint once for the confirmed action.
3. Check the HTTP status before reading `url`.
4. Send the user to the returned hosted URL.
5. Keep the billing URL out of logs and analytics.
6. Recheck [`GET /account`](/api-reference/account/get) after the user returns.

Read `plan` to confirm subscription state. Read `creditInfo.balance` before
tweet search, follower exports, writes, or monitor work.

Subscriptions are not the only funding path. A funded pay-as-you-go account can
continue eligible work while `plan` is `inactive`.

## Handle checkout retries

The service can reuse a matching open checkout. Use the latest returned
URL. A different tier request can replace an older open checkout.

Do not call this endpoint from a timer or an automatic retry loop.
For `429`, wait for `Retry-After`. For `401`, replace the credential first.

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

## Body

<ParamField body="tier" type="string">
  Pre-select `starter`, `pro`, or `business`. Omit the body when the user should
  choose on the hosted checkout.
</ParamField>

## Response

### 200 OK

<ResponseField name="url" type="string">
  Checkout URL (new subscribers) or billing portal URL (existing subscribers). Redirect the user to
  this URL.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable message describing the action taken.
</ResponseField>

<ResponseField name="status" type="string">
  One of: `already_subscribed`, `checkout_created`, `payment_issue`.
</ResponseField>

```json theme={null}
{
  "url": "https://xquik.com/billing/checkout/session",
  "message": "Complete checkout at the URL below to start your subscription.",
  "status": "checkout_created"
}
```

### 401 Unauthenticated

```json theme={null}
{ "error": "unauthenticated", "message": "Missing or invalid API key" }
```

Missing or invalid API key.

### 429 Rate limited

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

Too many requests. Wait for the `Retry-After` header before retrying.

<Note>
  **Related.** [Get Account](/api-reference/account/get) to check current subscription status and usage.
</Note>


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