# How to
Source: https://stackresolve.dev/docs/how-to

> The current, dated, cited way to do a task, so an agent builds from today.


A model builds from what it saw during training. By the time it ships your code, the library
it reached for may be unmaintained, the pattern may be the one the framework moved away from,
and nothing in the transcript will say so. `how_to` closes that gap: it researches the task
live, resolves the tools involved, and returns one dated, cited playbook.

Call it before writing code, not after a review finds the stale pattern.

## Call it

<CodeGroup>
```bash REST
curl https://api.stackresolve.dev/v1/how-to \
  -H "x-api-key: $STACKRESOLVE_API_KEY" \
  -H "content-type: application/json" \
  -d '{"task": "add rate limiting to a Next.js API route"}'
```

```text MCP
how_to({ task: "add rate limiting to a Next.js API route" })
```

```bash CLI
stackresolve how-to "add rate limiting to a Next.js API route"
```
</CodeGroup>

<ParamField body="task" type="string" required>
  What you are about to build, in plain language.
</ParamField>

```json Response
{
  "task": "add rate limiting to a Next.js API route",
  "asOf": "September 2026",
  "approach": "Use @upstash/ratelimit with Redis for distributed rate limiting in Next.js API routes...",
  "steps": [
    "Install dependencies: npm install @upstash/ratelimit @upstash/redis",
    "Configure rate limiter with algorithm choice: Ratelimit.slidingWindow(10, '10s')..."
  ],
  "gotchas": [
    "IP extraction must use x-forwarded-for or x-real-ip headers; req.ip is unreliable in serverless/edge environments"
  ],
  "deprecated": [
    "express-rate-limit in Next.js API routes - middleware pattern incompatible with Edge Runtime"
  ],
  "recommendedTools": [
    { "slug": "vercel", "name": "Vercel", "agentready": 93, "why": "Native platform; use @upstash/ratelimit with Vercel KV" }
  ],
  "sources": ["https://upstash.com/blog/nextjs-ratelimiting"]
}
```

<ResponseField name="asOf" type="string">
  The month the research ran. Quote it when you hand the approach to a user, so they know how
  fresh the answer is.
</ResponseField>
<ResponseField name="approach" type="string">
  The short version: what to use and why it is the current choice.
</ResponseField>
<ResponseField name="steps" type="string[]">
  Ordered, concrete steps. Written to be followed without a further search.
</ResponseField>
<ResponseField name="gotchas" type="string[]">
  The failures that show up after the happy path works, which is where training-cutoff memory
  is weakest.
</ResponseField>
<ResponseField name="deprecated" type="string[]">
  Patterns and packages to avoid, each with the reason. This is the field that catches a model
  reaching for what it learned two years ago.
</ResponseField>
<ResponseField name="recommendedTools" type="array">
  Products resolved for the task, scored and with a reason. Same shape as
  [resolve](/resolve).
</ResponseField>
<ResponseField name="sources" type="string[]">
  Every URL the answer was built from. Cite these rather than the answer itself.
</ResponseField>

<Note>Metered as `workflow_execution`. Results are cached per task, so a repeat question
returns instantly and costs nothing.</Note>

<Tip>Pair it with [resolve](/resolve): resolve picks the tool, how_to says how to use it as of
this month.</Tip>

