Discover/JetPunk API
live

JetPunk APIjetpunk.com

Access JetPunk quiz data via API. Search quizzes by keyword, browse by category tag, and retrieve full question/answer content for any quiz.

Endpoints
3
Updated
2mo ago

What is the JetPunk API?

The JetPunk API provides 3 endpoints for discovering and extracting trivia quiz data from JetPunk.com. Use search_quizzes to find quizzes by keyword and get back titles, URL paths, and take counts, or use get_quiz to retrieve a complete quiz including all question-answer pairs, column headers, categories, and description. The API covers thousands of quizzes across geography, history, science, and more.

Try it
Page number for pagination
Search keyword (e.g. 'Capitals', 'Countries')
api.parse.bot/scraper/8393ef45-4706-4d61-9693-127af45c4246/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/8393ef45-4706-4d61-9693-127af45c4246/search_quizzes?page=1&query=capitals' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace jetpunk-com-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.

"""
JetPunk Trivia API Parse Client

Search and discover trivia quizzes from JetPunk by category or tag, then access 
detailed quiz questions and answers to test your knowledge or build custom trivia experiences.

Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Any, Dict, List, Optional


class ParseClient:
    """Client for interacting with the JetPunk Trivia Parse API."""

    def __init__(self, api_key: Optional[str] = None):
        """
        Initialize the Parse API client.

        Args:
            api_key: API key for authentication. If not provided, reads from PARSE_API_KEY env var.
        """
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "8393ef45-4706-4d61-9693-127af45c4246"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")

        if not self.api_key:
            raise ValueError("API key not provided. Set PARSE_API_KEY environment variable.")

    def _call(
        self,
        endpoint: str,
        method: str = "POST",
        **params: Any
    ) -> Dict[str, Any]:
        """
        Make a request to the Parse API.

        Args:
            endpoint: The endpoint name (e.g., 'search_quizzes')
            method: HTTP method ('GET' or 'POST')
            **params: Query or body parameters

        Returns:
            Parsed JSON response
        """
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }

        if method.upper() == "GET":
            response = requests.get(url, headers=headers, params=params)
        elif method.upper() == "POST":
            response = requests.post(url, headers=headers, json=params)
        else:
            raise ValueError(f"Unsupported HTTP method: {method}")

        response.raise_for_status()
        return response.json()

    def search_quizzes(
        self,
        query: str,
        page: int = 1
    ) -> Dict[str, Any]:
        """
        Search for quizzes by keyword on JetPunk.

        Args:
            query: Search keyword (e.g., 'Capitals', 'Countries')
            page: Page number for pagination (default: 1)

        Returns:
            Dictionary containing quizzes list, page info, and has_next flag
        """
        return self._call(
            "search_quizzes",
            method="GET",
            query=query,
            page=page
        )

    def get_quizzes_by_tag(
        self,
        tag: str,
        page: int = 1
    ) -> Dict[str, Any]:
        """
        List quizzes in a specific category or tag.

        Args:
            tag: Tag or category name (e.g., 'geography', 'history', 'science')
            page: Page number for pagination (default: 1)

        Returns:
            Dictionary containing quizzes list, tag, and pagination info
        """
        return self._call(
            "get_quizzes_by_tag",
            method="GET",
            tag=tag,
            page=page
        )

    def get_quiz(self, path: str) -> Dict[str, Any]:
        """
        Get full details of a quiz, including title, description, categories, and all questions/answers.

        Args:
            path: The URL path of the quiz (e.g., '/quizzes/european-capitals-quiz')

        Returns:
            Dictionary containing quiz details, headers, and content (question/answer pairs)
        """
        return self._call(
            "get_quiz",
            method="GET",
            path=path
        )


def format_takes(takes_str: str) -> str:
    """Format takes count with commas for readability."""
    try:
        return f"{int(takes_str):,}"
    except (ValueError, TypeError):
        return takes_str


def print_quiz_table(quiz: Dict[str, Any], max_rows: int = 5) -> None:
    """Print quiz content in a formatted table."""
    headers = quiz.get('headers', [])
    content = quiz.get('content', [])

    if not headers or not content:
        print("   No content available")
        return

    # Calculate column widths
    col_widths = {header: len(header) for header in headers}
    for row in content[:max_rows]:
        for header in headers:
            col_widths[header] = max(col_widths[header], len(str(row.get(header, ''))))

    # Print header
    header_line = " | ".join(f"{h:<{col_widths[h]}}" for h in headers)
    print(f"   {header_line}")
    print(f"   {'-' * len(header_line)}")

    # Print rows
    for row in content[:max_rows]:
        row_line = " | ".join(f"{str(row.get(h, '')):<{col_widths[h]}}" for h in headers)
        print(f"   {row_line}")

    if len(content) > max_rows:
        print(f"   ... and {len(content) - max_rows} more")


if __name__ == "__main__":
    # Initialize the client
    client = ParseClient()

    print("🧠 JetPunk Trivia API - Practical Workflow\n")
    print("=" * 70)

    # Step 1: Search for quizzes about capitals
    print("\n📍 Step 1: Searching for 'capitals' quizzes...")
    search_results = client.search_quizzes(query="capitals", page=1)
    
    quizzes_list = search_results.get('quizzes', [])
    print(f"   ✓ Found {len(quizzes_list)} quizzes")
    print(f"   ✓ Has next page: {search_results.get('has_next', False)}")
    print(f"   ✓ Query: '{search_results.get('query')}'")

    # Step 2: Get top quiz from search results
    if quizzes_list:
        top_quiz_info = quizzes_list[0]
        print(f"\n📍 Step 2: Fetching details for top search result...")
        print(f"   Title: {top_quiz_info['title']}")
        print(f"   Takes: {format_takes(top_quiz_info['takes'])}")

        try:
            top_quiz = client.get_quiz(path=top_quiz_info['path'])
            print(f"   ✓ Loaded quiz ID: {top_quiz.get('id')}")
            print(f"   ✓ Questions: {len(top_quiz.get('content', []))}")
            print(f"   ✓ Categories: {', '.join(top_quiz.get('categories', []))}")

            print(f"\n   Quiz Description: {top_quiz.get('description', 'N/A')}")
            print(f"\n   Sample Q&A Data:")
            print_quiz_table(top_quiz, max_rows=4)

        except Exception as e:
            print(f"   ✗ Error loading quiz: {e}")

    # Step 3: Browse quizzes by geography tag
    print(f"\n\n📍 Step 3: Browsing 'geography' category...")
    geography_results = client.get_quizzes_by_tag(tag="geography", page=1)
    
    geo_quizzes = geography_results.get('quizzes', [])
    print(f"   ✓ Found {len(geo_quizzes)} geography quizzes")
    print(f"   ✓ Tag: {geography_results.get('tag')}")
    print(f"   ✓ Has next page: {geography_results.get('has_next', False)}")

    # Step 4: Fetch and display details for top geography quizzes
    print(f"\n📍 Step 4: Loading details for top 2 geography quizzes...")
    for idx, geo_quiz_info in enumerate(geo_quizzes[:2], 1):
        print(f"\n   [{idx}] {geo_quiz_info['title']}")
        print(f"       Takes: {format_takes(geo_quiz_info['takes'])}")

        try:
            geo_quiz = client.get_quiz(path=geo_quiz_info['path'])
            print(f"       ✓ Quiz ID: {geo_quiz.get('id')}")
            print(f"       ✓ Total questions: {len(geo_quiz.get('content', []))}")
            print(f"       ✓ Categories: {', '.join(geo_quiz.get('categories', []))}")

            print(f"\n       Sample Content:")
            print_quiz_table(geo_quiz, max_rows=3)

        except Exception as e:
            print(f"       ✗ Error: {e}")

    print("\n" + "=" * 70)
    print("✅ Workflow completed successfully!")
    print("\nYou can now:")
    print("  • Search for any quiz topic using search_quizzes()")
    print("  • Browse categories using get_quizzes_by_tag()")
    print("  • Extract Q&A data using get_quiz(path)")
All endpoints · 3 totalmissing one? ·

Search for quizzes by keyword on JetPunk. Returns a paginated list of matching quizzes with their paths and take counts.

Input
ParamTypeDescription
pageintegerPage number for pagination
queryrequiredstringSearch keyword (e.g. 'Capitals', 'Countries')
Response
{
  "type": "object",
  "fields": {
    "page": "integer, current page number",
    "query": "string, the search query echoed back",
    "quizzes": "array of objects with title, path, and takes",
    "has_next": "boolean, whether more pages exist"
  },
  "sample": {
    "data": {
      "page": 1,
      "query": "capitals",
      "quizzes": [
        {
          "path": "/quizzes/name-state-capitals",
          "takes": "1688350",
          "title": "U.S. State Capitals Quiz"
        },
        {
          "path": "/quizzes/european-capitals-quiz",
          "takes": "1584806",
          "title": "Europe Capitals Quiz"
        }
      ],
      "has_next": true
    },
    "status": "success"
  }
}

About the JetPunk API

Search and Browse Quizzes

The search_quizzes endpoint accepts a required query string (e.g. 'Capitals' or 'Countries') and an optional page integer for pagination. It returns a quizzes array where each object includes a title, a path (the quiz's URL slug), and a takes count indicating how many times that quiz has been completed. The has_next boolean tells you whether additional pages exist, making it straightforward to iterate through large result sets.

The get_quizzes_by_tag endpoint works similarly but filters by category. Pass a tag slug such as 'geography', 'history', or 'science', and receive a paginated list of quizzes under that tag. The normalized tag slug is echoed back in the response alongside the page and has_next fields. Both browse endpoints return the same quiz object shape, so you can feed the path field directly into the next endpoint.

Retrieving Full Quiz Content

Once you have a quiz path from either browse endpoint, pass it to get_quiz to retrieve complete quiz data. The response includes the quiz id, title, description, and a categories array listing all associated tags. The content field is an array of objects where each entry maps column header names to answer values — the headers array tells you what those column names are. For a capitals quiz, for example, headers might be ['Country', 'Capital'] and each content object maps those keys to the corresponding values. This structure supports both single-answer and multi-column quiz formats.

Coverage and Data Shape

Quiz take counts (takes) give a rough signal of popularity without requiring any additional calls. The path field returned in list endpoints is the canonical identifier for fetching quiz details — it matches the URL path on JetPunk.com. Categories returned in get_quiz responses are the same tag slugs accepted by get_quizzes_by_tag, so you can build category-aware workflows that chain all three endpoints.

Reliability & maintenance

The JetPunk API is a managed, monitored endpoint for jetpunk.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when jetpunk.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.

This isn't an official jetpunk.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.

Will this API break when the source site changes?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Build a trivia app seeded with JetPunk geography or history quizzes and their full question/answer data
  • Index quiz titles and take counts to surface the most-played quizzes in a given category tag
  • Generate flashcard decks from the content array returned by get_quiz
  • Search for quizzes by keyword to power a quiz recommendation or search feature
  • Extract categories arrays from quizzes to analyze how topics are distributed across the JetPunk catalog
  • Pipe multi-column quiz content (via the headers and content fields) into a database for structured trivia storage
  • Compare take counts across quizzes in the same tag to rank quiz popularity by subject
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does JetPunk have an official developer API?+
No. JetPunk does not publish an official developer API or documented data access program. This Parse API is the structured way to access JetPunk quiz and question data programmatically.
What does `get_quiz` return beyond the questions and answers?+
It returns the quiz id, title, description, a categories array of associated tag slugs, a headers array naming the column labels, and a content array where each object maps those header names to their corresponding values. This covers all the structured data visible on a quiz page.
Does the API return user scores, leaderboards, or per-user quiz history?+
Not currently. The API covers quiz metadata, category tags, take counts, and full question/answer content. User-specific data such as scores and leaderboards is not exposed. You can fork this API on Parse and revise it to add an endpoint targeting that data if it is publicly accessible on the site.
How does pagination work across the list endpoints?+
Both search_quizzes and get_quizzes_by_tag accept an optional page integer parameter (defaulting to the first page). Each response includes a has_next boolean. When has_next is true, increment page by one and repeat the request to fetch the next batch of results.
Can I filter quizzes by difficulty or date created?+
Not currently. The search and tag endpoints return title, path, and takes count per quiz, without difficulty ratings or creation dates. You can fork this API on Parse and revise it to add those fields if they appear on the relevant pages.
Page content last updated . Spec covers 3 endpoints from jetpunk.com.
Related APIs in EducationSee all →
sporcle.com API
Access Sporcle quizzes by slug, keyword search, or category. Retrieve quiz titles, questions, multiple-choice answers, hints, user ratings, and average scores.
funtrivia.com API
Search and browse thousands of trivia questions and quizzes across multiple categories, with the ability to filter by topic, difficulty, or find random challenges to test your knowledge. Discover trending topics, top-rated quizzes, and the latest additions to build custom trivia games or enhance your learning experience.
quizbowlpackets.com API
Search and browse thousands of quizbowl question sets across all competition levels, then access detailed metadata like difficulty, subjects, and download links for each packet. Find the perfect practice materials for High School, Collegiate, Middle School, or Pop Culture quizbowl competitions.
poki.com API
Discover and browse thousands of free online games with detailed information about genres, popularity, and platform compatibility. Find new games by exploring categories or searching through Poki's complete game catalog to access metadata and recommendations.
qconcursos.com API
Search and explore thousands of Brazilian public exam questions filtered by discipline, examining board, and subject to help prepare for concursos. Access detailed information about specific questions and browse the complete catalog of available exam topics and institutions.
Wikipedia API
Search Wikipedia and instantly access full article content on any topic, then explore related articles by browsing through Wikipedia categories. Retrieve article metadata, extracts, and navigate curated category trees to discover connected subjects.
unsplash.com API
Search Unsplash photos by keyword and retrieve image URLs, photographer info, and detailed photo metadata such as tags, EXIF, location, and related collections.
hackerrank.com API
Retrieve challenge scores, difficulty ratings, success ratios, and track-level ranking data from HackerRank's public practice platform. Browse challenges by track, view submission statistics, and access ranking metrics across all available tracks.