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

# Pricing

> Understand how AiQL bills credits across tools, ingestions, and queries

export const CostCalculator = () => {
  const RATES = {
    convertPerPage: 5,
    splitPerKWord: 1,
    shapePerKWord: 10,
    extractPerKWord: 30
  };
  const USD_PER_1K_CREDITS = 1.25;
  const [pages, setPages] = useState(10);
  const [wordsPerPage, setWordsPerPage] = useState(250);
  const [enabled, setEnabled] = useState({
    convert: true,
    split: true,
    shape: true,
    extract: true
  });
  const billed = credits => credits <= 0 ? 0 : Math.max(1, Math.ceil(credits));
  const words = pages * wordsPerPage;
  const steps = useMemo(() => {
    const k = words / 1000;
    return [{
      key: "convert",
      label: "Convert",
      detail: `${pages.toLocaleString()} pages × ${RATES.convertPerPage}`,
      credits: billed(pages * RATES.convertPerPage)
    }, {
      key: "split",
      label: "Split",
      detail: `${words.toLocaleString()} words × ${RATES.splitPerKWord} / 1K`,
      credits: billed(k * RATES.splitPerKWord)
    }, {
      key: "shape",
      label: "Shape",
      detail: `${words.toLocaleString()} words × ${RATES.shapePerKWord} / 1K`,
      credits: billed(k * RATES.shapePerKWord)
    }, {
      key: "extract",
      label: "Extract",
      detail: `${words.toLocaleString()} words × ${RATES.extractPerKWord} / 1K`,
      credits: billed(k * RATES.extractPerKWord)
    }];
  }, [pages, wordsPerPage]);
  const totalCredits = steps.reduce((sum, step) => enabled[step.key] ? sum + step.credits : sum, 0);
  const totalUsd = totalCredits * USD_PER_1K_CREDITS / 1000;
  const toggle = key => setEnabled(prev => ({
    ...prev,
    [key]: !prev[key]
  }));
  const sliderClass = "w-full mt-2 h-2 rounded-lg appearance-none cursor-pointer bg-zinc-950/10 dark:bg-white/10 accent-primary";
  return <div className="not-prose p-5 border border-zinc-950/10 dark:border-white/10 rounded-2xl bg-white dark:bg-zinc-900">
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-5">
        <label className="block text-sm font-medium text-zinc-950/70 dark:text-white/70">
          <span className="flex items-baseline justify-between">
            Pages
            <span className="font-mono text-zinc-950 dark:text-white">
              {pages.toLocaleString()}
            </span>
          </span>
          <input type="range" min="1" max="50" step="1" value={pages} onChange={e => setPages(Number.parseInt(e.target.value, 10))} className={sliderClass} />
        </label>
        <label className="block text-sm font-medium text-zinc-950/70 dark:text-white/70">
          <span className="flex items-baseline justify-between">
            Words per page
            <span className="font-mono text-zinc-950 dark:text-white">
              {wordsPerPage.toLocaleString()}
            </span>
          </span>
          <input type="range" min="1" max="500" step="1" value={wordsPerPage} onChange={e => setWordsPerPage(Number.parseInt(e.target.value, 10))} className={sliderClass} />
        </label>
      </div>

      <div className="mt-5 divide-y divide-zinc-950/5 dark:divide-white/5 border-y border-zinc-950/5 dark:border-white/5">
        {steps.map(step => {
    const isOn = enabled[step.key];
    return <label key={step.key} className="flex items-center gap-3 py-2.5 text-sm cursor-pointer">
              <input type="checkbox" checked={isOn} onChange={() => toggle(step.key)} className="h-4 w-4 rounded border-zinc-950/20 dark:border-white/20 accent-primary cursor-pointer" />
              <div className={"flex flex-1 items-center justify-between " + (isOn ? "" : "opacity-40")}>
                <div>
                  <span className="font-medium text-zinc-950 dark:text-white">
                    {step.label}
                  </span>
                  <span className="ml-2 text-zinc-950/50 dark:text-white/50">
                    {step.detail}
                  </span>
                </div>
                <span className="font-mono text-zinc-950/70 dark:text-white/70">
                  {isOn ? `${step.credits.toLocaleString()} cr` : "—"}
                </span>
              </div>
            </label>;
  })}
      </div>

      <div className="mt-5 flex items-end justify-between">
        <div>
          <p className="mt-1 text-2xl font-semibold text-zinc-950 dark:text-white">
            {totalCredits.toLocaleString()}{" "}
            <span className="text-base font-normal text-zinc-950/50 dark:text-white/50">
              credits
            </span>
          </p>
        </div>
        <p className="text-2xl font-semibold text-primary dark:text-white">
          ${totalUsd.toFixed(2)}
        </p>
      </div>
    </div>;
};

AiQL bills in **credits**. Every operation consumes credits based on the work it performs — pages processed for document tools, pages ingested for the pipeline, and words processed for queries.

## Plans

Pick the plan that fits your team. Every plan includes a monthly credit allowance, and paid plans add pay-as-you-go credits on top.

<Columns cols={2}>
  <Card title="Free" icon="seedling">
    **\$0** / month

    * **Includes** 10K credits
    * Upgrade to Starter for pay-as-you-go credits
    * 1 user
    * Basic support
  </Card>

  <Card title="Starter" icon="rocket">
    **\$50** / month

    * **Includes** 40K credits
    * **Pay-as-you-go** up to 400K credits
    * 5 users
    * Basic support
  </Card>

  <Card title="Pro" icon="building">
    **\$500** / month

    * **Includes** 400K credits
    * **Pay-as-you-go** up to 4,000K credits
    * 10 users
    * Slack support
  </Card>

  <Card title="Enterprise" icon="shield">
    **Custom** — talk to sales

    * Volume discount on credits
    * 5x higher rate limits
    * Enterprise SSO
    * SaaS or Hybrid cloud deployment
    * Dedicated account manager
  </Card>
</Columns>

| Plan             | Free   | Starter            | Pro                  | Enterprise |
| ---------------- | ------ | ------------------ | -------------------- | ---------- |
| Price            | \$0/mo | \$50/mo            | \$500/mo             | Custom     |
| Included credits | 10K    | 40K                | 400K                 | Custom     |
| Pay-as-you-go    | —      | up to 400K credits | up to 4,000K credits | Custom     |
| Users            | 1      | 5                  | 10                   | Custom     |
| Support          | Basic  | Basic              | Slack                | Dedicated  |

<Note>
  AiQL runs on a credit-based system, where each action — converting, splitting, shaping, extracting, ingesting, or querying — costs a certain number of credits. **1,000 credits = \$1.25.**
</Note>

## Tools

Individual tools let you run a single pipeline step on demand. Each tool is billed per page processed.

| Tool    | Endpoint        | Cost                  | Formula                   |
| ------- | --------------- | --------------------- | ------------------------- |
| Convert | `POST /convert` | 5 credits / page      | `pages × 5`               |
| Split   | `POST /split`   | 1 credit / 1K words   | `ceil(words / 1000 × 1)`  |
| Shape   | `POST /shape`   | 10 credits / 1K words | `ceil(words / 1000 × 10)` |
| Extract | `POST /extract` | 30 credits / 1K words | `ceil(words / 1000 × 30)` |

<Note>
  Pages are counted after `convert` normalizes the source document. Word counts for `split`, `shape`, and `extract` are measured against the converted text. The credit amount is rounded up, so every billed operation costs at least 1 credit.
</Note>

## Ingestion pipeline

An ingestion runs the full `convert → split → shape → extract` pipeline as one managed job. You are billed for each step it runs, using the same per-tool rates above.

| Operation | Endpoint                       | Cost                    | Formula                             |
| --------- | ------------------------------ | ----------------------- | ----------------------------------- |
| Ingestion | `POST /ingestions`             | Sum of each step's cost | `convert + split + shape + extract` |
| Retry     | `POST /ingestions/{id}/retry`  | Sum of re-run steps     | cost of steps re-executed           |
| Cancel    | `POST /ingestions/{id}/cancel` | Free                    | —                                   |

<Note>
  An ingestion is billed as the sum of the tool steps it runs: `convert` (per page) plus `split`, `shape`, and `extract` (per 1K words). A cancelled ingestion is only billed for the steps that finished before cancellation, and a retry only bills for the steps it re-executes.
</Note>

### Estimate a single file

Enter the page and word counts for one file to estimate its cost. Toggle steps to model a full ingestion or an individual tool run.

<CostCalculator />

## Queries

Queries run over data you have already ingested into a workspace. They are billed per query based on the number of words processed, rounded up to a minimum of 1 credit.

| Operation | Endpoint        | Cost                  | Formula                   |
| --------- | --------------- | --------------------- | ------------------------- |
| Query     | `POST /queries` | 10 credits / 1K words | `ceil(words / 1000 × 10)` |

<Note>
  Word counts include both the query input and the matched content returned. Every query has a minimum charge of 1 credit, and listing, retrieving, and deleting saved queries is free.
</Note>

## Free operations

The following operations never consume credits:

* Managing workspaces (`/workspaces`)
* Listing, retrieving, and deleting ingestions and queries
* Cancelling an in-flight ingestion
* Health checks

## Best practices

<AccordionGroup>
  <Accordion title="Use the pipeline for end-to-end work">
    Prefer `POST /ingestions` over chaining individual tools. You pay the same per-step rates, but get managed orchestration, retries, and cancellation handling for free.
  </Accordion>

  <Accordion title="Run individual tools for targeted work">
    Reach for `convert`, `split`, `shape`, or `extract` when you only need a single step, or when you want to inspect intermediate output before committing to a full ingestion.
  </Accordion>

  <Accordion title="Scope your queries">
    Keep prompts focused and constrain the result set. Fewer words in and out means fewer credits per query.
  </Accordion>
</AccordionGroup>
