A batch with hundreds of videos doesn't come back in one response. GET /api/v1/transcripts/{batch_id} pages its items with skip/limit, and tells you when you're done with has_more. This is the pattern to use for anything beyond a small test batch â a channel batch can easily hold thousands of videos.
This isn't an arbitrary limit for its own sake: without it, polling a 1,000-video batch would mean one response carrying a thousand transcripts' worth of text (plus metadata, if you asked for it), which is slow to generate, slow to transfer, and awkward to hold in memory all at once. Paging spreads that cost across however many requests you actually need.
Paging through one batch's items
curl -s "https://scriptube.me/api/v1/transcripts/BATCH_ID?skip=0&limit=50" \
-H "X-API-Key: YOUR_API_KEY"
limit defaults to (and caps at) 50 items per page. The response carries:
| Field | Meaning |
|---|---|
items | This page's items. |
item_count | Total items in the whole batch. |
skip / limit | Echoes what you asked for. |
has_more | true if there's another page after this one. |
Loop until has_more is false:
import requests
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
BASE = "https://scriptube.me"
batch_id = "00000000-0000-0000-0000-000000000000"
items = []
skip = 0
limit = 50 # max page size = resolve_inline_cache_limit (default 50)
while True:
page = requests.get(
f"{BASE}/api/v1/transcripts/{batch_id}",
headers=HEADERS,
params={"skip": skip, "limit": limit},
).json()
items.extend(page["items"])
if not page["has_more"]:
break
skip += limit
print(f"loaded {len(items)} of {page.get('item_count')} items")
If you only need metadata or timestamps, add include_metadata=true or include_segments=true to the same request â they apply per page, not per batch, so the cost of a bigger payload is spread across your loop instead of landing in one giant response.
A concrete worked case: a 4,000-video channel batch, at the default 50 per page, is 80 requests to walk end to end. At 60 reads/minute that's under two minutes sequentially â comfortably inside the limit for a one-off export, but worth knowing if you're paginating several large batches from the same key at once, since they share the same per-key budget.
A different page: the list of batches
GET /api/v1/transcripts (no ID) lists your batches themselves â summary rows, no items, no transcript text. It has its own skip/limit (default 20, max 100) and its own has_more/total, independent of how many items are inside any one batch:
# Paginating the batch LIST itself (a different endpoint, a different page shape)
batches = []
skip = 0
while True:
page = requests.get(
f"{BASE}/api/v1/transcripts",
headers=HEADERS,
params={"skip": skip, "limit": 100},
).json()
batches.extend(page["batches"])
if not page["has_more"]:
break
skip += 100
Filter this list to one partner's batches with external_id=, or to the batches created by a single mixed submission with submission_id= â see tagging batches.
Processing pages as you go, not after
Don't accumulate every item into one list before doing anything with it if the batch is large â process each page as it arrives and discard it:
skip = 0
completed, failed = 0, 0
while True:
page = requests.get(
f"{BASE}/api/v1/transcripts/{batch_id}",
headers=HEADERS,
params={"skip": skip, "limit": 50},
).json()
for item in page["items"]:
if item["status"] == "completed":
completed += 1
# write item["transcript_text"] to storage here, not to a growing list
else:
failed += 1
if not page["has_more"]:
break
skip += 50
print(f"{completed} completed, {failed} failed/skipped")
This keeps memory flat regardless of batch size, and means a script that's writing results to disk or a database doesn't lose everything if it crashes on page 70 of 80 â pages 1 through 69 are already saved.
Common mistakes
- Assuming one page is the whole batch. Always check
has_more; a batch of 300 videos is 6 pages at the default limit. - Re-requesting metadata on every poll while still processing. Poll with no extra params first; only pull
include_metadata/include_segmentsonce you're paging through acompletedbatch â a larger payload per page is wasted while most items are still queued. - Confusing item pagination with batch-list pagination. They're separate endpoints with separate
skip/limitvalues â incrementing one doesn't affect the other. - Hardcoding
limit=50as a guess. It's the documented default/max, not an arbitrary round number â raising it in your request doesn't get you a bigger page, it just gets capped back down to 50.
Pagination on exports
Exports (GET /api/v1/transcripts/{batch_id}/export) are streamed rather than paginated with skip/limit â request a format and the whole file comes back as one response, built incrementally server-side rather than loaded into memory all at once. You don't need a pagination loop for exports; it's only the JSON-shaped batch poll (GET /api/v1/transcripts/{batch_id} with no ?format=) that pages.
Frequently asked
What's the actual max limit value? 50 for item pagination (resolve_inline_cache_limit), 100 for the batch list. Asking for more than the max is simply capped, not rejected.
Does pagination cost credits? No â reading a batch, at any page, any number of times, is always free. Only the original submit charges credits.
Can I paginate backward, or jump to a specific item? Only forward by skip. If you need to resume a crashed job, store the last successfully processed skip value and restart from there.
Does the item order change between pages if the batch is still processing? Item order within a batch is stable once set at submission, so paging through a still-running batch is safe â you won't see items shift position or duplicate across pages as more of them complete.
Next steps
- Browse your whole library â a third, related pagination surface for everything you've ever processed.
- Channel batch limits â why large batches happen in the first place.
- The complete API guide.
Full reference: API documentation.