Important: These examples use different source documents and are not sequential. Making a scanned PDF searchable adds a searchable text layer, but it does not create interactive form fields. To fill or extract form fields, the source PDF must already contain those fields.
Make a PDF Searchable, Fill PDF Form Fields, and Extract Field Values in Python
This tutorial contains two independent PDF.co examples:
- Example 1 applies OCR to a scanned PDF so its text becomes searchable.
- Example 2 fills and reads existing interactive form fields in a different PDF.
Requirements
Install the Requests library:
pip install requestsStore your PDF.co API key in an environment variable named PDFCO_API_KEY.
On macOS or Linux:
export PDFCO_API_KEY="YOUR_PDFCO_API_KEY"On Windows PowerShell:
$env:PDFCO_API_KEY="YOUR_PDFCO_API_KEY"The examples use public sample files. Replace their URLs with your own directly accessible files when adapting the code.
Step 1: Example 1: Make a Scanned PDF Searchable
This example uses the PDF.co Make Searchable endpoint to apply OCR to a scanned PDF.
OCR recognizes text contained in the page image and adds a searchable text layer. It does not detect or create fillable text boxes, checkboxes, radio buttons, or other form controls.
The sample uses this stable PDF.co test file:
https://pdfco-test-files.s3.us-west-2.amazonaws.com/pdf-make-searchable/sample.pdfComplete Python Script
Save the following code as make_searchable.py:
import os
import requests
API_KEY = os.environ["PDFCO_API_KEY"]
BASE_URL = "https://api.pdf.co/v1"
SOURCE_FILE_URL = (
"https://pdfco-test-files.s3.us-west-2.amazonaws.com/"
"pdf-make-searchable/sample.pdf"
)
OUTPUT_FILE = "searchable-output.pdf"
headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json",
}
payload = {
"url": SOURCE_FILE_URL,
"name": OUTPUT_FILE,
"lang": "eng",
"pages": "",
"async": False,
}
response = requests.post(
f"{BASE_URL}/pdf/makesearchable",
json=payload,
headers=headers,
timeout=120,
)
response.raise_for_status()
result = response.json()
if result.get("error"):
raise RuntimeError(result.get("message", "PDF.co processing failed."))
result_url = result["url"]
file_response = requests.get(result_url, timeout=120)
file_response.raise_for_status()
with open(OUTPUT_FILE, "wb") as output:
output.write(file_response.content)
print(f"Searchable PDF saved as {OUTPUT_FILE}")Run the script:
python make_searchable.pyThe generated searchable-output.pdf should allow text selection and searching. It will not contain interactive form fields unless the source PDF already had them.
For larger documents, use asynchronous processing and monitor the returned jobId with the Job Check endpoint. See the PDF.co Make Searchable documentation.
Step 2: Example 2: Fill and Extract Existing PDF Form Fields
This is a separate demonstration using an IRS Form 1040 PDF that already contains interactive form fields.
The source file is:
https://pdfco-test-files.s3.us-west-2.amazonaws.com/pdf-form/f1040.pdfThis example performs two related operations:
- Fill selected fields in the existing form.
- Pass the resulting PDF URL to the PDF Forms Info Reader and print its field names and values.
The output of the fill request is used as the input for field extraction.
Complete Python Script
Save the following code as fill_and_extract_fields.py:
import os
import requests
API_KEY = os.environ["PDFCO_API_KEY"]
BASE_URL = "https://api.pdf.co/v1"
SOURCE_FORM_URL = (
"https://pdfco-test-files.s3.us-west-2.amazonaws.com/"
"pdf-form/f1040.pdf"
)
OUTPUT_FILE = "filled-f1040.pdf"
headers = {
"x-api-key": API_KEY,
"Content-Type": "application/json",
}
fields_string = (
"1;topmostSubform[0].Page1[0].f1_02[0];John A. Doe|"
"1;topmostSubform[0].Page1[0].FilingStatus[0].c1_01[1];true|"
"1;topmostSubform[0].Page1[0].YourSocial_ReadOrderControl[0]."
"f1_04[0];123456789"
)
fill_payload = {
"url": SOURCE_FORM_URL,
"name": OUTPUT_FILE,
"fieldsString": fields_string,
"async": False,
}
fill_response = requests.post(
f"{BASE_URL}/pdf/edit/add",
json=fill_payload,
headers=headers,
timeout=120,
)
fill_response.raise_for_status()
fill_result = fill_response.json()
if fill_result.get("error"):
raise RuntimeError(
fill_result.get("message", "PDF.co could not fill the form.")
)
filled_pdf_url = fill_result["url"]
file_response = requests.get(filled_pdf_url, timeout=120)
file_response.raise_for_status()
with open(OUTPUT_FILE, "wb") as output:
output.write(file_response.content)
print(f"Filled PDF saved as {OUTPUT_FILE}")
info_payload = {
"url": filled_pdf_url,
"async": False,
}
info_response = requests.post(
f"{BASE_URL}/pdf/info/fields",
json=info_payload,
headers=headers,
timeout=120,
)
info_response.raise_for_status()
info_result = info_response.json()
if info_result.get("error"):
raise RuntimeError(
info_result.get("message", "PDF.co could not read the form fields.")
)
fields = (
info_result
.get("info", {})
.get("FieldsInfo", {})
.get("Fields", [])
)
if not fields:
print("No interactive form fields were found.")
else:
print("\nForm fields and values:")
for field in fields:
field_name = field.get("FieldName", "")
field_value = field.get("Value", "")
field_type = field.get("Type", "")
page_index = field.get("PageIndex", "")
print(
f"Page {page_index} | "
f"{field_type} | "
f"{field_name} => {field_value}"
)Run the script:
python fill_and_extract_fields.pyThe script creates filled-f1040.pdf and prints the interactive fields and their current values.
Understanding fieldsString
The fieldsString parameter uses this format:
page;fieldName;valueSeparate multiple fields with a vertical bar:
page;fieldName;value|page;fieldName;valueFor example:
1;CustomerName;John Doe|1;Approved;trueThe correct page number, field name, and accepted value depend on the source form. Use the PDF Forms Info Reader or the PDF.co PDF Edit Add Helper to inspect the available fields before filling them.
The PDF Add endpoint supports fieldsString as well as structured field objects.
Step 3: Important Differences Between the Examples
Searchable Text
A searchable PDF contains a text layer. Users can search for, select, and copy recognized text.
Interactive Form Fields
Interactive form fields are separate PDF objects with names, types, values, and coordinates. Examples include:
- Text boxes
- Checkboxes
- Radio buttons
- List boxes
- Combo boxes
OCR does not create these objects. A scanned form can become searchable while still having no fillable fields.
If you need to add new interactive fields to a scanned form, that requires a separate form-field creation operation after OCR.
Temporary Output URLs
PDF.co returns temporary URLs for generated files. Download or transfer the output to permanent storage before the link expires.
Conclusion
You completed two PDF.co workflows in Python:
- Applying OCR to make a scanned PDF searchable
- Filling and extracting existing interactive form fields
Related Tutorials

