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
- Sign in at pangram.com and open the API page of your dashboard.
- 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.
- Create an API key and copy it.
Add the credential in qbash
- Open Connectors, then Pangram, and click Connect.
- Give the credential a name and paste the API key. qbash checks the key with Pangram before saving it.
- 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_aiwaits up tomax_wait_secondsfor Pangram to finish, 60 seconds by default and 300 at most. When the wait runs out,completeisFalseand the result isNone. Pass thetask_idtoget_detectionlater instead of starting a new check, because Pangram already billed the first one.fraction_ai,fraction_ai_assistedandfraction_humanrun from 0 to 1 and add up to 1. Each window'sstart_indexandend_indexare character offsets into the result'stext, which Pangram may normalize, so they can differ from offsets in the text you sent.modeltakes a selector fromlist_models.defaultfollows Pangram's current model, andpangram-4pins 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_linkanddetect_ai_file_with_dashboard_linkpublish 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_filereads 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_plagiarismreturns each copied passage with the source URL it matched and its character offsets in the text.percent_plagiarizedis 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.