Inference API
The Inference API accepts text, creates a task, and returns a task ID.
Poll the task endpoint until the stage is STAGE_SUCCESS or STAGE_FAILED.
- POST https://text.external-api.pangram.com/task
- Request JSON Object:
text (string) – The input text to analyze with Pangram.
public_dashboard_link (boolean) – Whether to include a public dashboard link in the completed response. Defaults to false.
- Response JSON Object:
task_id (string) – The ID of the async inference task.
Request Headers
{ "Content-Type": "application/json", "x-api-key": "<api-key>" }
Request Body
{ "text": "<text>", "public_dashboard_link": false }
Example Request
POST https://text.external-api.pangram.com/task HTTP/1.1 Content-Type: application/json x-api-key: your_api_key_here { "text": "The text to analyze", "public_dashboard_link": true }
Example Response
{ "task_id": "123e4567-e89b-12d3-a456-426614174000" }
- GET https://text.external-api.pangram.com/task/(string: task_id)
- Response JSON Object:
task_id (string) – The ID of the async inference task. Present while the task is in progress.
stage (string) – Current task stage. Terminal stages are
STAGE_SUCCESSandSTAGE_FAILED.text (string) – The input text that was analyzed. Present on success.
version (string) – The API version identifier. Present on success.
headline (string) – Classification headline summarizing the result. Present on success.
prediction (string) – Long-form prediction string representing the classification. Present on success.
prediction_short (string) – Short-form prediction string. Present on success.
fraction_ai (float) – Fraction of text classified as AI-written (0.0-1.0). Present on success.
fraction_ai_assisted (float) – Fraction of text classified as AI-assisted (0.0-1.0). Present on success.
fraction_human (float) – Fraction of text classified as human-written (0.0-1.0). Present on success.
num_ai_segments (int) – Number of text segments classified as AI. Present on success.
num_ai_assisted_segments (int) – Number of text segments classified as AI-assisted. Present on success.
num_human_segments (int) – Number of text segments classified as human. Present on success.
windows (array) – List of analyzed text windows. Each window includes text, label, ai_assistance_score, confidence, start_index, end_index, word_count, and token_length. Present on success.
dashboard_link (string) – A link to the dashboard page containing the full classification result. Present on success when public_dashboard_link is true.
Request Headers
{ "x-api-key": "<api-key>" }
In-Progress Response
{ "task_id": "123e4567-e89b-12d3-a456-426614174000", "stage": "STAGE_PREPROCESSING" }
Success Response
{ "stage": "STAGE_SUCCESS", "text": "The text to analyze", "version": "3.0", "headline": "AI Detected", "prediction": "We are confident that this document contains AI-generated or AI-assisted content.", "prediction_short": "Mixed", "fraction_ai": 0.70, "fraction_ai_assisted": 0.20, "fraction_human": 0.10, "num_ai_segments": 7, "num_ai_assisted_segments": 2, "num_human_segments": 1, "dashboard_link": "https://www.pangram.com/history/123e4567-e89b-12d3-a456-426614174000", "windows": [ { "text": "The text to analyze", "label": "AI-Generated", "ai_assistance_score": 0.85, "confidence": "High", "start_index": 0, "end_index": 19, "word_count": 4, "token_length": 5 }, { "text": "with classification", "label": "Moderately AI-Assisted", "ai_assistance_score": 0.45, "confidence": "Medium", "start_index": 20, "end_index": 49, "word_count": 2, "token_length": 3 } ] }
Failed Response
{ "stage": "STAGE_FAILED", "text": "", "version": "", "headline": "preprocessing: Input text contains no valid text after preprocessing", "prediction": "", "prediction_short": "", "fraction_ai": 0.0, "fraction_ai_assisted": 0.0, "fraction_human": 0.0, "num_ai_segments": 0, "num_ai_assisted_segments": 0, "num_human_segments": 0, "windows": [] }
Bulk API
The Bulk API accepts many texts, queues them as asynchronous AI detection work,
and returns a bulk job ID. Poll the bulk status endpoint until the status is
succeeded, failed, or partial.
Completion time depends on the number and length of submitted items and current system load. Use the bulk status endpoint to monitor progress.
Bulk metadata and results are retained for 48 hours after the job reaches a
terminal status. created_at and completed_at are returned as Unix epoch
seconds encoded as strings, such as "1760000000.0".
The launch bulk limit is 1,000 billable units per request. A billable unit is one started 1,000-word block per valid item, with a minimum of one unit per item. There is no separate item-count limit, but normal request-body limits still apply.
- POST https://text.external-api.pangram.com/bulk
- Request JSON Object:
text (array) – A list of input texts. Provide either
textoritems.items (array) – A list of objects with
textand optionalidfields. Provide eitheritemsortext.
- Response JSON Object:
bulk_id (string) – The ID of the bulk job.
status (string) – Initial status, usually
queuedorfailedif every item failed immediate validation.total_items (int) – Total number of submitted items.
accepted_items (array) – Items accepted for processing. Each item includes
index, optionalid, andtask_id.failed_items (array) – Items that failed immediate validation. Each item includes
index, optionalid,stage, anderror.
Request Headers
{ "Content-Type": "application/json", "x-api-key": "<api-key>" }
Request Body
{ "items": [ {"id": "row-001", "text": "First text to analyze"}, {"id": "row-002", "text": "Second text to analyze"} ] }
Example Response
{ "bulk_id": "blk_123", "status": "queued", "total_items": 2, "accepted_items": [ {"index": 0, "id": "row-001", "task_id": "123e4567-e89b-12d3-a456-426614174000"}, {"index": 1, "id": "row-002", "task_id": "223e4567-e89b-12d3-a456-426614174000"} ], "failed_items": [] }
- GET https://text.external-api.pangram.com/bulk/(string: bulk_id)
- Response JSON Object:
bulk_id (string) – The ID of the bulk job.
status (string) – One of
queued,running,succeeded,failed, orpartial.total_items (int) – Total number of submitted items.
accepted (int) – Number of items accepted for processing.
succeeded (int) – Number of items that completed successfully.
failed (int) – Number of items that failed.
created_at (string) – Job creation timestamp as Unix epoch seconds encoded as a string.
completed_at (string) – Job completion timestamp as Unix epoch seconds encoded as a string, or null while non-terminal.
Example Response
{ "bulk_id": "blk_123", "status": "partial", "total_items": 3, "accepted": 2, "succeeded": 2, "failed": 1, "created_at": "1760000000.0", "completed_at": "1760000030.0" }
- GET https://text.external-api.pangram.com/bulk/(string: bulk_id)/items
- Query Parameters:
offset (int) – Zero-based item offset. Defaults to 0.
limit (int) – Maximum number of items to return. Defaults to 100 and can be at most 1000.
- Response JSON Object:
bulk_id (string) – The ID of the bulk job.
offset (int) – The returned page offset.
limit (int) – The returned page limit.
total_items (int) – Total number of submitted items.
items (array) – Item metadata. Each item includes
index, optionalid,task_id,stage, and optionalerror.
Example Response
{ "bulk_id": "blk_123", "offset": 0, "limit": 100, "total_items": 2, "items": [ { "index": 0, "id": "row-001", "task_id": "123e4567-e89b-12d3-a456-426614174000", "stage": "STAGE_SUCCESS", "error": null } ] }
- GET https://text.external-api.pangram.com/bulk/(string: bulk_id)/results
- Query Parameters:
offset (int) – Zero-based item offset. Defaults to 0.
limit (int) – Maximum number of items to return. Defaults to 100 and can be at most 1000.
- Response JSON Object:
bulk_id (string) – The ID of the bulk job.
offset (int) – The returned page offset.
limit (int) – The returned page limit.
total_items (int) – Total number of submitted items.
items (array) – Result items. Successful completed items include
resultwith the same shape returned by the task endpoint. In-progress items haveresultset to null.failed_items (array) – Failed item metadata for the requested page.
Example Response
{ "bulk_id": "blk_123", "offset": 0, "limit": 100, "total_items": 2, "items": [ { "index": 0, "id": "row-001", "task_id": "123e4567-e89b-12d3-a456-426614174000", "stage": "STAGE_SUCCESS", "error": null, "result": { "text": "First text to analyze", "version": "3.3", "prediction": "We believe this is human-written", "prediction_short": "Human", "fraction_ai": 0.0, "fraction_ai_assisted": 0.0, "fraction_human": 1.0, "headline": "Human Written", "num_ai_segments": 0, "num_ai_assisted_segments": 0, "num_human_segments": 1, "windows": [] } } ], "failed_items": [] }
File Upload API
The File Upload API accepts one or more files as multipart/form-data and
returns one result object per uploaded file. Use this endpoint when you want
Pangram to extract text from .docx, .pdf, or .rtf documents and
create AI detection results. Each result uses the same prediction schema as the
text API, with the extracted text and uploaded filename included. When
public_dashboard_link is true, each result also includes a
dashboard_link.
- POST https://file-external.api.pangram.com/
Request Headers
Do not set
Content-Typemanually for multipart requests. HTTP clients add the multipart boundary automatically.{ "x-api-key": "<api-key>" }
Multipart Form Fields
Field
Type
Required
Description
filesfile[]
Yes
.docx,.pdf, or.rtffiles to analyze. Include this form field once per uploaded file.public_dashboard_linkboolean
No
Whether to create and return a
dashboard_linkfor each uploaded file. Defaults tofalse.Example Request
POST https://file-external.api.pangram.com/ HTTP/1.1 x-api-key: your_api_key_here Content-Type: multipart/form-data; boundary=... --... Content-Disposition: form-data; name="files"; filename="document.docx" Content-Type: application/octet-stream <file bytes> --... Content-Disposition: form-data; name="public_dashboard_link" true --...--
Example cURL
curl -s -X POST https://file-external.api.pangram.com \ -H "x-api-key: $PANGRAM_API_KEY" \ -F "files=@path/to/first.docx" \ -F "files=@path/to/second.pdf" \ -F "public_dashboard_link=true"
Example Response
[ { "filename": "document.docx", "text": "Extracted document text...", "version": "3.3", "headline": "Human Written", "prediction": "We believe this is human-written", "prediction_short": "Human", "fraction_ai": 0.0, "fraction_ai_assisted": 0.0, "fraction_human": 1.0, "num_ai_segments": 0, "num_ai_assisted_segments": 0, "num_human_segments": 1, "windows": [], "dashboard_link": "https://www.pangram.com/history/123e4567-e89b-12d3-a456-426614174000" } ]
Errors
400 Bad Request- The multipart request is missing a file or includes invalid form data.401 Unauthorized- Thex-api-keyis missing or invalid.402 Payment Required- The account has insufficient credits.413 Payload Too Large- The upload exceeds the maximum supported file size.415 Unsupported Media Type- The uploaded file type is not supported.422 Unprocessable Entity- Thefilesfield is missing, the form data is invalid, or Pangram could not extract valid text from the uploaded file.500 Internal Server Error- There was an error processing the upload.
Plagiarism Detection API
The Plagiarism Detection API checks text for potential plagiarism by comparing it against online content.
- POST https://plagiarism.api.pangram.com
- Request JSON Object:
text (string) – The input text to check for plagiarism.
- Response JSON Object:
text (string) – The input text that was checked.
plagiarism_detected (bool) – Whether plagiarism was detected in the text.
plagiarized_content (array) – A list of detected plagiarized content, including source URLs and matched text.
total_sentences (int) – Total number of sentences in the input text.
plagiarized_sentences (array) – List of sentences that were detected as plagiarized.
percent_plagiarized (float) – Percentage of the text that was detected as plagiarized.
Request Headers
{ "Content-Type": "application/json", "x-api-key": "<api-key>" }
Request Body
{ "text": "<text>" }
Example Request
POST https://plagiarism.api.pangram.com HTTP/1.1 Content-Type: application/json x-api-key: your_api_key_here { "text": "The text to check for plagiarism" }
Example Response
{ "text": "The text to check for plagiarism", "plagiarism_detected": true, "plagiarized_content": [ { "source_url": "https://example.com/source", "matched_text": "The text to check for plagiarism", "similarity_score": 0.95 } ], "total_sentences": 1, "plagiarized_sentences": 1, "percent_plagiarized": 100.0 }
Errors
The API may return the following error codes:
400 Bad Request- If the request body is not properly formatted.401 Unauthorized- If thex-api-keyis missing or invalid.402 Payment Required- If the account has insufficient credits.403 Forbidden- If the API key does not own the requested task.404 Not Found- If the requested task does not exist.422 Unprocessable Entity- If the input text is invalid.429 Too Many Requests- If the API key exceeds its configured rate limit.500 Internal Server Error- If there is an error processing the request.
Please reach out at support@pangram.com if you are running into errors with your requests.