Skip to main content

Connect Pangram

Tasks call Pangram through qbash.integrations.pangram with an API key you store on the Connectors page. Pangram estimates how much of a text was written by AI, edited with AI or written by a person, and labels each segment of the text. The connector checks single texts, many texts at once in a bulk job, and stored PDF or Word documents. It also checks text against online sources for plagiarism.

After you connect Pangram, you can add its tools to a qbash MCP server for ChatGPT, Claude and other MCP clients, or call it from a Python task. The Pangram MCP server page lists what the connector can do.

Pangram bills the key's API credits for each call, by the number of words checked. Bulk jobs cost less per word than single checks.

Create an API key​

  1. Sign in at pangram.com and open the API page of your dashboard.
  2. Add API credits, or turn on auto-refill so calls keep working when the balance runs low. Calls fail with a 402 error when the account has no credits.
  3. Create an API key and copy it.

Add the credential in qbash​

  1. Open Connectors, then Pangram, and click Connect.
  2. Give the credential a name and paste the API key. qbash checks the key with Pangram before saving it.
  3. In the task editor, open Resources → Integrations, and select the credential. See Connect resources.

To edit the credential later, leave the key blank to keep the saved one.

Call Pangram from a task​

This task checks a draft passed in as a task input and logs Pangram's verdict and the segments it labeled as AI.

draft = qbash.inputs.get("draft")

check = qbash.integrations.pangram.detect_ai(text=draft, max_wait_seconds=120)

if not check["complete"]:
qbash.log(f'Pangram is still checking. Read it later with get_detection(task_id="{check["task_id"]}").')
else:
result = check["result"]
qbash.log(f'{result["prediction_short"]}: {result["fraction_ai"]:.0%} AI, {result["fraction_ai_assisted"]:.0%} AI-assisted')

for window in result["windows"]:
if window["label"] != "Human Written":
qbash.log(f'{window["label"]} ({window["confidence"]}): {window["text"][:120]}')

The SDK Reference lists every method with its parameters and return values.

Check many texts at once​

submit_bulk checks a list of texts in one job. Pass items with an id of your own for each text, such as a row or ticket ID, and the ID comes back with that text's result.

job = qbash.integrations.pangram.submit_bulk(items=[
{"id": "review-101", "text": "..."},
{"id": "review-102", "text": "..."},
])
bulk_id = job["bulk"]["bulk_id"]

status = qbash.integrations.pangram.get_bulk(bulk_id=bulk_id, max_wait_seconds=300)
while not status["complete"]:
qbash.sleep(60)
status = qbash.integrations.pangram.get_bulk(bulk_id=bulk_id, max_wait_seconds=300)

cursor = None
while True:
page = qbash.integrations.pangram.list_bulk_results(bulk_id=bulk_id, cursor=cursor)
for item in page["items"]:
if item["result"]:
qbash.log(f'{item["id"]}: {item["result"]["prediction_short"]}')
cursor = page["next_cursor"]
if cursor is None:
break

Add test data​

Pangram needs no account data, so any text works. For a clear AI result, ask a chat model to write a few paragraphs on any topic. For a human result, use something you wrote yourself before 2022. Pasting the two into one text gives a Mixed result with a window for each part. Keep test texts short, since every call spends credits.

Details that affect results​

  • detect_ai waits up to max_wait_seconds for Pangram to finish, 60 seconds by default and 300 at most. When the wait runs out, complete is False and the result is None. Pass the task_id to get_detection later instead of starting a new check, because Pangram already billed the first one.
  • fraction_ai, fraction_ai_assisted and fraction_human run from 0 to 1 and add up to 1. Each window's start_index and end_index are character offsets into the result's text, which Pangram may normalize, so they can differ from offsets in the text you sent.
  • model takes a selector from list_models. default follows Pangram's current model, and pangram-4 pins one generation. The file methods always use Pangram's default model.
  • A bulk job is capped at 1,000 billable units, counted per item as one unit for each started 100 words. A bigger job returns a 413 error, so split it into smaller jobs. Pangram keeps bulk jobs and their results for 48 hours after the job finishes.
  • detect_ai_with_dashboard_link and detect_ai_file_with_dashboard_link publish the result as a pangram.com page that anyone with the link can open. Both count as writes, so a Test run skips them unless writes are turned on.
  • detect_ai_file reads a file from task inputs or from another connector's file result. Pangram extracts the text, and it answers 415 for a file type it does not read.
  • check_plagiarism returns each copied passage with the source URL it matched and its character offsets in the text. percent_plagiarized is the share of sentences that matched, from 0 to 100.
  • Pangram limits how many requests each key can make. The connector retries a rate-limited call once, and a task that sends many single checks should use a bulk job instead.