Poll status
curl --request GET \
--url https://api.example.com/api/v1/convert/status/:jobIdimport requests
url = "https://api.example.com/api/v1/convert/status/:jobId"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/convert/status/:jobId', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/convert/status/:jobId",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/convert/status/:jobId"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/convert/status/:jobId")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/convert/status/:jobId")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyAPI reference
Poll status
Check the status of an async conversion job
GET
/
api
/
v1
/
convert
/
status
/
:jobId
Poll status
curl --request GET \
--url https://api.example.com/api/v1/convert/status/:jobIdimport requests
url = "https://api.example.com/api/v1/convert/status/:jobId"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/api/v1/convert/status/:jobId', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/convert/status/:jobId",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/convert/status/:jobId"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/convert/status/:jobId")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/convert/status/:jobId")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyPoll the status of a conversion job that was started with
"async": true or that timed out during synchronous processing.
Request
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_API_TOKEN | Yes |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
jobId | string | Yes | The job ID returned from the convert endpoint |
Example request
curl https://api.formswrite.com/api/v1/convert/status/456 \
-H "Authorization: Bearer YOUR_API_TOKEN"
Response
The response includes the current job state, progress information, and the result when the job completes.| Field | Type | Description |
|---|---|---|
success | boolean | Whether the API call succeeded |
jobId | string | The job ID |
state | string | Current job state: waiting, active, completed, or failed |
progress | number | Progress percentage (0–100) |
currentStep | string | Description of the current processing step |
result | object | Conversion result (only present when state is completed) |
error | string | Error message (only present when state is failed) |
Job states
| State | Description |
|---|---|
waiting | Job is queued and waiting to be processed |
active | Job is currently being processed |
completed | Job finished successfully — check the result field |
failed | Job failed — check the error field |
Response examples
Processing
{
"success": true,
"jobId": "456",
"state": "active",
"progress": 45,
"currentStep": "Extracting questions"
}
Completed
{
"success": true,
"jobId": "456",
"state": "completed",
"progress": 100,
"currentStep": "",
"result": {
"success": true,
"documentId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
"documentName": "Biology Exam",
"isQuiz": true,
"mergedContent": {
"title": "Biology Exam",
"questions": [...]
}
}
}
Async mode currently runs analysis only, not the format conversion. The
result from the status endpoint contains the extracted questions (mergedContent) but not the final converted file or URL. To get the file, call the convert endpoint again without async: true — that single call analyzes and converts in one step.For now, prefer synchronous mode unless you specifically need the analyzed-questions payload separately from the conversion step.Failed
{
"success": true,
"jobId": "456",
"state": "failed",
"progress": 0,
"currentStep": "",
"error": "Document could not be accessed. Please check sharing permissions."
}
Not found
{
"success": false,
"message": "Job not found"
}
Polling strategy
We recommend polling every 3–5 seconds. Most documents are analyzed within 30–60 seconds.async function waitForConversion(jobId, apiToken) {
const maxAttempts = 60;
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch(
`https://api.formswrite.com/api/v1/convert/status/${jobId}`,
{ headers: { Authorization: `Bearer ${apiToken}` } }
);
const data = await response.json();
if (data.state === 'completed') {
return data.result;
}
if (data.state === 'failed') {
throw new Error(data.error);
}
// Wait 3 seconds before next poll
await new Promise(resolve => setTimeout(resolve, 3000));
}
throw new Error('Polling timed out');
}
⌘I