Skip to main content

Two kinds of limits

Pull/story applies two independent limits to every request:
  1. Rate limit — how many requests per minute you can make
  2. Minute quota — how much generated video you can create per month

Rate limits

Endpoint typeLimit
POST /v1/stories (creation)10 / minute
GET /v1/stories/:id (polling)120 / minute
All other endpoints60 / minute
When exceeded you receive:
HTTP 429 Too Many Requests

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Retry after 18 seconds.",
    "retry_after": 18
  }
}
The Retry-After HTTP header is also set.

Minute quota

PlanVideo minutes per monthPrice
Free10 min$0
Pro120 min$19 / mo
Each generated pull story consumes minutes equal to its video duration. A short PR is usually ~1 minute; a large PR is 3-5 minutes. When you run out of minutes:
HTTP 402 Payment Required

{
  "error": {
    "code": "insufficient_minutes",
    "message": "Monthly video quota exceeded.",
    "minutes_remaining": 0,
    "minutes_required": 3,
    "upgrade_url": "https://pullstory.com/dashboard/billing"
  }
}

Handling limits in your code

async function createStory(payload) {
  for (let attempt = 0; attempt < 3; attempt++) {
    const res = await fetch("https://pullstory.com/api/v1/stories", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.PULLSTORY_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(payload),
    });

    if (res.status === 429) {
      const retryAfter = Number(res.headers.get("retry-after") ?? 10);
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      continue;
    }

    return res.json();
  }
}

Checking your quota

Get your remaining minutes at any time:
curl https://pullstory.com/api/v1/me/usage \
  -H "Authorization: Bearer $PULLSTORY_API_KEY"
{
  "plan": "pro",
  "period_start": "2026-04-01T00:00:00Z",
  "period_end": "2026-05-01T00:00:00Z",
  "minutes_included": 120,
  "minutes_used": 47,
  "minutes_remaining": 73
}

Need more?

If 120 minutes isn’t enough for your team, email us — we’ll get you on a custom plan.