# QStash

> An HTTP message queue with retries, delays and schedules, in one command.

```bash
npx extraorbital add qstash
```

```txt
✓ Provisioned qstash/default
✓ Wrote 4 variables to .env

  QSTASH_URL, QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY, QSTASH_NEXT_SIGNING_KEY
```

A project that mentions `QSTASH_URL` or `QSTASH_TOKEN` gets this from
[`extraorbital provision`](/docs/quickstart#how-autopilot-decides) without naming it.

## What it writes

| Variable | Example |
| --- | --- |
| `QSTASH_URL` | `https://qstash.extraorbital.dev/v2/publish` |
| `QSTASH_TOKEN` | `eyJVc2VySUQ…` |
| `QSTASH_CURRENT_SIGNING_KEY` | `sig_7f2a…` |
| `QSTASH_NEXT_SIGNING_KEY` | `sig_9c4e…` |

Publish a message with a target URL and QStash delivers it with retries, delays and
schedules. There is no connection to hold open, which suits serverless functions and
agents that sleep between runs. The two signing keys let you verify deliveries and
rotate without downtime.

## Options

```bash
npx extraorbital add qstash [--slug <name>]
```

| Flag | Default | Description |
| --- | --- | --- |
| `--slug` | `default` | A second, fully separate set of credentials |

## Prototype allowance

**1,000 messages per day and 50 GB of bandwidth free** on the Prototype plan,
counted across your whole account and shared by up to five queues. Past it,
$1.00/100K messages — our own cost, with nothing added, and retries are still
free — on [a paid plan](/pricing).

## Use it

Publish with a delay:

```ts title="publish.ts"
import { Client } from "@upstash/qstash";

const qstash = new Client({ token: process.env.QSTASH_TOKEN! });

await qstash.publishJSON({
  url: "https://my-agent.example.com/api/jobs",
  body: { task: "summarize", docId: "doc-42" },
  delay: 60, // seconds
});
```

Verify on the receiving end, so only your queue can trigger the handler:

```ts title="app/api/jobs/route.ts"
import { Receiver } from "@upstash/qstash";

const receiver = new Receiver({
  currentSigningKey: process.env.QSTASH_CURRENT_SIGNING_KEY!,
  nextSigningKey: process.env.QSTASH_NEXT_SIGNING_KEY!,
});

export async function POST(request: Request) {
  const body = await request.text();
  const ok = await receiver.verify({
    signature: request.headers.get("Upstash-Signature")!,
    body,
  });
  if (!ok) return new Response("Invalid signature", { status: 401 });

  return Response.json({ received: JSON.parse(body) });
}
```

## Next

- [Redis](/docs/resources/redis) — lists and streams you poll yourself
- [Pricing](/pricing) — plans, allowances and rates

---

More for agents: [Docs index](https://extraorbital.dev/sitemap.md) · [llms.txt](https://extraorbital.dev/llms.txt) · [agents.md](https://extraorbital.dev/agents.md)
