Nutrient

SDK

Cloud

Workflow

Integrations

2 credits

Java OCR API

Unlock text from scanned documents and images with the Java OCR API, providing seamless generation of searchable, interactive PDFs.

Built for PDF workflows

Unlike generic OCR tools, Nutrient is optimized for PDFs, preserving layout, handling embedded fonts, and supporting searchable PDF output for seamless integration into document pipelines.

Accurate OCR in 20 languages

With support for 20 widely used languages, Nutrient delivers reliable text extraction across multilingual documents, ideal for global business use cases.

Try it instantly on Zapier

Extract text from scanned PDFs in Google Drive using our Zapier integration. Itโ€™s a no-code way to turn scanned PDFs into searchable, editable documents โ€” automatically.

Nutrient is used by

Try it out

This example will run English language OCR on your uploaded document, making any text in the document selectable and searchable.

1

Use Your Free API Calls

Sign up and receive 200 credits / month for free, or log in to automatically add your API key to sample code. If you are not sure how credits are consumed read more in our pricing documentation , or check out this guide on calculating credit usage.

Add a File

Add a scanned PDF named document.pdf to your project folder. You can also use our sample file. The file name is case sensitive. Make sure the file name matches the file name in the sample code.

Run the Code

Copy the code and run it from the same folder you added the files to. For more information, see our language-specific getting started guides.

View the Results

Open result.pdf in your project folder to view the results.

Basic API Advanced API
curl -X POST https://api.nutrient.io/processor/ocr \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F file=@document.pdf \
  -F data='{
      "language": "english"
    }'
curl -X POST https://api.nutrient.io/processor/ocr ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F file=@document.pdf ^
  -F data="{\"language\": \"english\"}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "file",
        "document.pdf",
        RequestBody.create(
          MediaType.parse("application/pdf"),
          new File("document.pdf")
        )
      )
      .addFormDataPart(
        "data",
        new JSONObject()
          .put("language", "english").toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.nutrient.io/processor/ocr")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.nutrient.io/processor/ocr");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("file", "document.pdf")
        .AddParameter("data", new JsonObject
        {
          ["language"] = "english"
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('data', JSON.stringify({
  language: "english"
}))
formData.append('file', fs.createReadStream('document.pdf'))

;(async () => {
  try {
    const response = await axios.post('https://api.nutrient.io/processor/ocr', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/processor/ocr',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'file': open('document.pdf', 'rb')
  },
  data = {
    'data': json.dumps({
      'language': 'english'
    })
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.nutrient.io/processor/ocr',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'data' => '{
      "language": "english"
    }',
    'file' => new CURLFILE('document.pdf')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.nutrient.io/processor/ocr HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="data"
Content-Type: application/json

{
  "language": "english"
}
--customboundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf

(file data)
--customboundary--
curl -X POST https://api.nutrient.io/build \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F scanned=@document.pdf \
  -F instructions='{
      "parts": [
        {
          "file": "scanned"
        }
      ],
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }'
curl -X POST https://api.nutrient.io/build ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F scanned=@document.pdf ^
  -F instructions="{\"parts\": [{\"file\": \"scanned\"}], \"actions\": [{\"type\": \"ocr\", \"language\": \"english\"}]}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "scanned",
        "document.pdf",
        RequestBody.create(
          MediaType.parse("application/pdf"),
          new File("document.pdf")
        )
      )
      .addFormDataPart(
        "instructions",
        new JSONObject()
          .put("parts", new JSONArray()
            .put(new JSONObject()
              .put("file", "scanned")
            )
          )
          .put("actions", new JSONArray()
            .put(new JSONObject()
              .put("type", "ocr")
              .put("language", "english")
            )
          ).toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.nutrient.io/build")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.nutrient.io/build");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("scanned", "document.pdf")
        .AddParameter("instructions", new JsonObject
        {
          ["parts"] = new JsonArray
          {
            new JsonObject
            {
              ["file"] = "scanned"
            }
          },
          ["actions"] = new JsonArray
          {
            new JsonObject
            {
              ["type"] = "ocr",
              ["language"] = "english"
            }
          }
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('instructions', JSON.stringify({
  parts: [
    {
      file: "scanned"
    }
  ],
  actions: [
    {
      type: "ocr",
      language: "english"
    }
  ]
}))
formData.append('scanned', fs.createReadStream('document.pdf'))

;(async () => {
  try {
    const response = await axios.post('https://api.nutrient.io/build', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'scanned': open('document.pdf', 'rb')
  },
  data = {
    'instructions': json.dumps({
      'parts': [
        {
          'file': 'scanned'
        }
      ],
      'actions': [
        {
          'type': 'ocr',
          'language': 'english'
        }
      ]
    })
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.nutrient.io/build',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'instructions' => '{
      "parts": [
        {
          "file": "scanned"
        }
      ],
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }',
    'scanned' => new CURLFILE('document.pdf')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.nutrient.io/build HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": "scanned"
    }
  ],
  "actions": [
    {
      "type": "ocr",
      "language": "english"
    }
  ]
}
--customboundary
Content-Disposition: form-data; name="scanned"; filename="document.pdf"
Content-Type: application/pdf

(scanned data)
--customboundary--
Using Postman? Try this tool in our Postman collection to start using the API with a single click. Read more 

Your API key

API Comparison

Recommended

OCR API

Streamlined API for performing OCR on documents. Perfect for most use cases.

Features

  • Simple request format
  • Minimal configuration required
  • Purpose-built for specific tasks

Example

curl -X POST https://api.nutrient.io/processor/ocr \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F file=@document.pdf \
  -F data='{
      "language": "english"
    }'
curl -X POST https://api.nutrient.io/processor/ocr ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F file=@document.pdf ^
  -F data="{\"language\": \"english\"}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "file",
        "document.pdf",
        RequestBody.create(
          MediaType.parse("application/pdf"),
          new File("document.pdf")
        )
      )
      .addFormDataPart(
        "data",
        new JSONObject()
          .put("language", "english").toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.nutrient.io/processor/ocr")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.nutrient.io/processor/ocr");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("file", "document.pdf")
        .AddParameter("data", new JsonObject
        {
          ["language"] = "english"
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('data', JSON.stringify({
  language: "english"
}))
formData.append('file', fs.createReadStream('document.pdf'))

;(async () => {
  try {
    const response = await axios.post('https://api.nutrient.io/processor/ocr', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/processor/ocr',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'file': open('document.pdf', 'rb')
  },
  data = {
    'data': json.dumps({
      'language': 'english'
    })
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.nutrient.io/processor/ocr',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'data' => '{
      "language": "english"
    }',
    'file' => new CURLFILE('document.pdf')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.nutrient.io/processor/ocr HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="data"
Content-Type: application/json

{
  "language": "english"
}
--customboundary
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf

(file data)
--customboundary--
Advanced

Build API

Maximum flexibility and advanced features for complex workflows.

Features

  • Multi-part document support
  • Advanced actions and transformations
  • Workflow orchestration

Example

curl -X POST https://api.nutrient.io/build \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F scanned=@document.pdf \
  -F instructions='{
      "parts": [
        {
          "file": "scanned"
        }
      ],
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }'
curl -X POST https://api.nutrient.io/build ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F scanned=@document.pdf ^
  -F instructions="{\"parts\": [{\"file\": \"scanned\"}], \"actions\": [{\"type\": \"ocr\", \"language\": \"english\"}]}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "scanned",
        "document.pdf",
        RequestBody.create(
          MediaType.parse("application/pdf"),
          new File("document.pdf")
        )
      )
      .addFormDataPart(
        "instructions",
        new JSONObject()
          .put("parts", new JSONArray()
            .put(new JSONObject()
              .put("file", "scanned")
            )
          )
          .put("actions", new JSONArray()
            .put(new JSONObject()
              .put("type", "ocr")
              .put("language", "english")
            )
          ).toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.nutrient.io/build")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.nutrient.io/build");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("scanned", "document.pdf")
        .AddParameter("instructions", new JsonObject
        {
          ["parts"] = new JsonArray
          {
            new JsonObject
            {
              ["file"] = "scanned"
            }
          },
          ["actions"] = new JsonArray
          {
            new JsonObject
            {
              ["type"] = "ocr",
              ["language"] = "english"
            }
          }
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('instructions', JSON.stringify({
  parts: [
    {
      file: "scanned"
    }
  ],
  actions: [
    {
      type: "ocr",
      language: "english"
    }
  ]
}))
formData.append('scanned', fs.createReadStream('document.pdf'))

;(async () => {
  try {
    const response = await axios.post('https://api.nutrient.io/build', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'scanned': open('document.pdf', 'rb')
  },
  data = {
    'instructions': json.dumps({
      'parts': [
        {
          'file': 'scanned'
        }
      ],
      'actions': [
        {
          'type': 'ocr',
          'language': 'english'
        }
      ]
    })
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.nutrient.io/build',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'instructions' => '{
      "parts": [
        {
          "file": "scanned"
        }
      ],
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }',
    'scanned' => new CURLFILE('document.pdf')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.nutrient.io/build HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": "scanned"
    }
  ],
  "actions": [
    {
      "type": "ocr",
      "language": "english"
    }
  ]
}
--customboundary
Content-Disposition: form-data; name="scanned"; filename="document.pdf"
Content-Type: application/pdf

(scanned data)
--customboundary--

Getting Started

The following section will walk you through how to best make use of all the functionality the OCR API provides.

The Basics of OCR

Letโ€™s start with the basics. The OCR API allows you to take files in any supported format and make any text in them selectable and searchable. This is useful for images and scanned documents. To learn more about OCR itself, see here.

For our first example, weโ€™ll run OCR on a single image file. To do this, add a page1.jpg file to the same folder as your code. You can use any image containing text, or use our provided sample page.

Run the code, and youโ€™ll get a result.pdf with your page OCRed. Our example sets the OCR language to English. If your content is in a different language, make sure to update the language property accordingly. You can find a list of all supported languages at the bottom of this page.

Code to perform OCR:

curl -X POST https://api.nutrient.io/processor/ocr \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F file=@page1.jpg \
  -F data='{
      "language": "english"
    }'
curl -X POST https://api.nutrient.io/processor/ocr ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F file=@page1.jpg ^
  -F data="{\"language\": \"english\"}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "file",
        "page1.jpg",
        RequestBody.create(
          MediaType.parse("image/jpeg"),
          new File("page1.jpg")
        )
      )
      .addFormDataPart(
        "data",
        new JSONObject()
          .put("language", "english").toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.nutrient.io/processor/ocr")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.nutrient.io/processor/ocr");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("file", "page1.jpg")
        .AddParameter("data", new JsonObject
        {
          ["language"] = "english"
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('data', JSON.stringify({
  language: "english"
}))
formData.append('file', fs.createReadStream('page1.jpg'))

;(async () => {
  try {
    const response = await axios.post('https://api.nutrient.io/processor/ocr', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/processor/ocr',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'file': open('page1.jpg', 'rb')
  },
  data = {
    'data': json.dumps({
      'language': 'english'
    })
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.nutrient.io/processor/ocr',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'data' => '{
      "language": "english"
    }',
    'file' => new CURLFILE('page1.jpg')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.nutrient.io/processor/ocr HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="data"
Content-Type: application/json

{
  "language": "english"
}
--customboundary
Content-Disposition: form-data; name="file"; filename="page1.jpg"
Content-Type: image/jpeg

(file data)
--customboundary--

Advanced OCR

While running OCR on a single page is useful, often youโ€™ll have a folder full of scanned pages that you want to both run OCR on and merge into a single searchable PDF.

Luckily, this is easy; pass in multiple images โ€” one for each page in your request โ€” and Nutrient DWS Processor API will merge all of them into a PDF before running OCR on it.

Add more files in the same folder as your code and run the updated code. You can duplicate and rename the existing file you have, or you can add some other images containing text.

Code to perform OCR on multiple pages:

curl -X POST https://api.nutrient.io/build \
  -H "Authorization: Bearer your_api_key_here" \
  -o result.pdf \
  --fail \
  -F page1.jpg=@/path/to/page1.jpg \
  -F page2.jpg=@/path/to/page2.jpg \
  -F page3.jpg=@/path/to/page3.jpg \
  -F page4.jpg=@/path/to/page4.jpg \
  -F instructions='{
      "parts": [
        {
          "file": "page1.jpg"
        },
        {
          "file": "page2.jpg"
        },
        {
          "file": "page3.jpg"
        },
        {
          "file": "page4.jpg"
        }
      ],
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }'
curl -X POST https://api.nutrient.io/build ^
  -H "Authorization: Bearer your_api_key_here" ^
  -o result.pdf ^
  --fail ^
  -F page1.jpg=@/path/to/page1.jpg ^
  -F page2.jpg=@/path/to/page2.jpg ^
  -F page3.jpg=@/path/to/page3.jpg ^
  -F page4.jpg=@/path/to/page4.jpg ^
  -F instructions="{\"parts\": [{\"file\": \"page1.jpg\"}, {\"file\": \"page2.jpg\"}, {\"file\": \"page3.jpg\"}, {\"file\": \"page4.jpg\"}], \"actions\": [{\"type\": \"ocr\", \"language\": \"english\"}]}"
package com.example.pspdfkit;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import org.json.JSONArray;
import org.json.JSONObject;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public final class PspdfkitApiExample {
  public static void main(final String[] args) throws IOException {
    final RequestBody body = new MultipartBody.Builder()
      .setType(MultipartBody.FORM)
      .addFormDataPart(
        "page1.jpg",
        "/path/to/page1.jpg",
        RequestBody.create(
          MediaType.parse("image/jpeg"),
          new File("/path/to/page1.jpg")
        )
      )
      .addFormDataPart(
        "page2.jpg",
        "/path/to/page2.jpg",
        RequestBody.create(
          MediaType.parse("image/jpeg"),
          new File("/path/to/page2.jpg")
        )
      )
      .addFormDataPart(
        "page3.jpg",
        "/path/to/page3.jpg",
        RequestBody.create(
          MediaType.parse("image/jpeg"),
          new File("/path/to/page3.jpg")
        )
      )
      .addFormDataPart(
        "page4.jpg",
        "/path/to/page4.jpg",
        RequestBody.create(
          MediaType.parse("image/jpeg"),
          new File("/path/to/page4.jpg")
        )
      )
      .addFormDataPart(
        "instructions",
        new JSONObject()
          .put("parts", new JSONArray()
            .put(new JSONObject()
              .put("file", "page1.jpg")
            )
            .put(new JSONObject()
              .put("file", "page2.jpg")
            )
            .put(new JSONObject()
              .put("file", "page3.jpg")
            )
            .put(new JSONObject()
              .put("file", "page4.jpg")
            )
          )
          .put("actions", new JSONArray()
            .put(new JSONObject()
              .put("type", "ocr")
              .put("language", "english")
            )
          ).toString()
      )
      .build();

    final Request request = new Request.Builder()
      .url("https://api.nutrient.io/build")
      .method("POST", body)
      .addHeader("Authorization", "Bearer your_api_key_here")
      .build();

    final OkHttpClient client = new OkHttpClient()
      .newBuilder()
      .build();

    final Response response = client.newCall(request).execute();

    if (response.isSuccessful()) {
      Files.copy(
        response.body().byteStream(),
        FileSystems.getDefault().getPath("result.pdf"),
        StandardCopyOption.REPLACE_EXISTING
      );
    } else {
      // Handle the error
      throw new IOException(response.body().string());
    }
  }
}
using System;
using System.IO;
using System.Net;
using RestSharp;

namespace PspdfkitApiDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      var client = new RestClient("https://api.nutrient.io/build");

      var request = new RestRequest(Method.POST)
        .AddHeader("Authorization", "Bearer your_api_key_here")
        .AddFile("page1.jpg", "/path/to/page1.jpg")
        .AddFile("page2.jpg", "/path/to/page2.jpg")
        .AddFile("page3.jpg", "/path/to/page3.jpg")
        .AddFile("page4.jpg", "/path/to/page4.jpg")
        .AddParameter("instructions", new JsonObject
        {
          ["parts"] = new JsonArray
          {
            new JsonObject
            {
              ["file"] = "page1.jpg"
            },
            new JsonObject
            {
              ["file"] = "page2.jpg"
            },
            new JsonObject
            {
              ["file"] = "page3.jpg"
            },
            new JsonObject
            {
              ["file"] = "page4.jpg"
            }
          },
          ["actions"] = new JsonArray
          {
            new JsonObject
            {
              ["type"] = "ocr",
              ["language"] = "english"
            }
          }
        }.ToString());

      request.AdvancedResponseWriter = (responseStream, response) =>
      {
        if (response.StatusCode == HttpStatusCode.OK)
        {
          using (responseStream)
          {
            using var outputFileWriter = File.OpenWrite("result.pdf");
            responseStream.CopyTo(outputFileWriter);
          }
        }
        else
        {
          var responseStreamReader = new StreamReader(responseStream);
          Console.Write(responseStreamReader.ReadToEnd());
        }
      };

      client.Execute(request);
    }
  }
}
// This code requires Node.js. Do not run this code directly in a web browser.

const axios = require('axios')
const FormData = require('form-data')
const fs = require('fs')

const formData = new FormData()
formData.append('instructions', JSON.stringify({
  parts: [
    {
      file: "page1.jpg"
    },
    {
      file: "page2.jpg"
    },
    {
      file: "page3.jpg"
    },
    {
      file: "page4.jpg"
    }
  ],
  actions: [
    {
      type: "ocr",
      language: "english"
    }
  ]
}))
formData.append('page1.jpg', fs.createReadStream('/path/to/page1.jpg'))
formData.append('page2.jpg', fs.createReadStream('/path/to/page2.jpg'))
formData.append('page3.jpg', fs.createReadStream('/path/to/page3.jpg'))
formData.append('page4.jpg', fs.createReadStream('/path/to/page4.jpg'))

;(async () => {
  try {
    const response = await axios.post('https://api.nutrient.io/build', formData, {
      headers: formData.getHeaders({
        'Authorization': 'Bearer your_api_key_here'
      }),
      responseType: "stream"
    })

    response.data.pipe(fs.createWriteStream("result.pdf"))
  } catch (e) {
    const errorString = await streamToString(e.response.data)
    console.log(errorString)
  }
})()

function streamToString(stream) {
  const chunks = []
  return new Promise((resolve, reject) => {
    stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)))
    stream.on("error", (err) => reject(err))
    stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
  })
}
import requests
import json

response = requests.request(
  'POST',
  'https://api.nutrient.io/build',
  headers = {
    'Authorization': 'Bearer your_api_key_here'
  },
  files = {
    'page1.jpg': open('/path/to/page1.jpg', 'rb'),
    'page2.jpg': open('/path/to/page2.jpg', 'rb'),
    'page3.jpg': open('/path/to/page3.jpg', 'rb'),
    'page4.jpg': open('/path/to/page4.jpg', 'rb')
  },
  data = {
    'instructions': json.dumps({
      'parts': [
        {
          'file': 'page1.jpg'
        },
        {
          'file': 'page2.jpg'
        },
        {
          'file': 'page3.jpg'
        },
        {
          'file': 'page4.jpg'
        }
      ],
      'actions': [
        {
          'type': 'ocr',
          'language': 'english'
        }
      ]
    })
  },
  stream = True
)

if response.ok:
  with open('result.pdf', 'wb') as fd:
    for chunk in response.iter_content(chunk_size=8096):
      fd.write(chunk)
else:
  print(response.text)
  exit()
<?php

$FileHandle = fopen('result.pdf', 'w+');

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.nutrient.io/build',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_POSTFIELDS => array(
    'instructions' => '{
      "parts": [
        {
          "file": "page1.jpg"
        },
        {
          "file": "page2.jpg"
        },
        {
          "file": "page3.jpg"
        },
        {
          "file": "page4.jpg"
        }
      ],
      "actions": [
        {
          "type": "ocr",
          "language": "english"
        }
      ]
    }',
    'page1.jpg' => new CURLFILE('/path/to/page1.jpg'),
    'page2.jpg' => new CURLFILE('/path/to/page2.jpg'),
    'page3.jpg' => new CURLFILE('/path/to/page3.jpg'),
    'page4.jpg' => new CURLFILE('/path/to/page4.jpg')
  ),
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer your_api_key_here'
  ),
  CURLOPT_FILE => $FileHandle,
));

$response = curl_exec($curl);

curl_close($curl);

fclose($FileHandle);

POST https://api.nutrient.io/build HTTP/1.1
Content-Type: multipart/form-data; boundary=--customboundary
Authorization: Bearer your_api_key_here

--customboundary
Content-Disposition: form-data; name="instructions"
Content-Type: application/json

{
  "parts": [
    {
      "file": "page1.jpg"
    },
    {
      "file": "page2.jpg"
    },
    {
      "file": "page3.jpg"
    },
    {
      "file": "page4.jpg"
    }
  ],
  "actions": [
    {
      "type": "ocr",
      "language": "english"
    }
  ]
}
--customboundary
Content-Disposition: form-data; name="page1.jpg"; filename="/path/to/page1.jpg"
Content-Type: image/jpeg

(page1.jpg data)
--customboundary
Content-Disposition: form-data; name="page2.jpg"; filename="/path/to/page2.jpg"
Content-Type: image/jpeg

(page2.jpg data)
--customboundary
Content-Disposition: form-data; name="page3.jpg"; filename="/path/to/page3.jpg"
Content-Type: image/jpeg

(page3.jpg data)
--customboundary
Content-Disposition: form-data; name="page4.jpg"; filename="/path/to/page4.jpg"
Content-Type: image/jpeg

(page4.jpg data)
--customboundary--

Supported Languages

The OCR action supports a wide range of languages for text extraction. You can specify languages using either:

  • Full language name (lowercase, e.g., english, german) - available for commonly used languages
  • ISO 639-2 language code (e.g., eng, deu) - available for all languages
  • ISO 639-2 language code with variant (e.g., chi_sim_vert or deu_frak)
Description Language code Full language name
๐Ÿ‡ฟ๐Ÿ‡ฆ Afrikaansafr
๐Ÿ‡ฆ๐Ÿ‡ฑ Albaniansqi
๐Ÿ‡ช๐Ÿ‡น Amharicamh
๐Ÿ‡ธ๐Ÿ‡ฆ Arabicara
๐Ÿ‡ฆ๐Ÿ‡ฒ Armenianhye
๐Ÿ‡ฎ๐Ÿ‡ณ Assameseasm
๐Ÿ‡ฆ๐Ÿ‡ฟ Azerbaijaniaze
๐Ÿ‡ฆ๐Ÿ‡ฟ Azerbaijani - Cyrillicaze_cyrl
๐Ÿ‡ช๐Ÿ‡ธ Basqueeus
๐Ÿ‡ง๐Ÿ‡พ Belarusianbel
๐Ÿ‡ง๐Ÿ‡ฉ Bengaliben
๐Ÿ‡ง๐Ÿ‡ฆ Bosnianbos
๐Ÿ‡ซ๐Ÿ‡ท Bretonbre
๐Ÿ‡ง๐Ÿ‡ฌ Bulgarianbul
๐Ÿ‡ฒ๐Ÿ‡ฒ Burmesemya
๐Ÿ‡ช๐Ÿ‡ธ Catalan; Valenciancat
๐Ÿ‡ต๐Ÿ‡ญ Cebuanoceb
๐Ÿ‡ฐ๐Ÿ‡ญ Central Khmerkhm
๐Ÿ‡บ๐Ÿ‡ธ Cherokeechr
๐Ÿ‡จ๐Ÿ‡ณ Chinese - Simplifiedchi_sim
๐Ÿ‡จ๐Ÿ‡ณ Chinese - Simplified (Vertical)chi_sim_vert
๐Ÿ‡น๐Ÿ‡ผ Chinese - Traditionalchi_tra
๐Ÿ‡น๐Ÿ‡ผ Chinese - Traditional (Vertical)chi_tra_vert
๐Ÿ‡ซ๐Ÿ‡ท Corsicancos
๐Ÿ‡ญ๐Ÿ‡ท Croatianhrvcroatian
๐Ÿ‡จ๐Ÿ‡ฟ Czechcesczech
๐Ÿ‡ฉ๐Ÿ‡ฐ Danishdandanish
๐Ÿ‡ฉ๐Ÿ‡ฐ Danish - Frakturdan_frak
๐Ÿ‡ฒ๐Ÿ‡ป Dhivehi; Maldiviandiv
๐Ÿ‡ณ๐Ÿ‡ฑ Dutch; Flemishnlddutch
๐Ÿ‡ง๐Ÿ‡น Dzongkhadzo
๐Ÿ‡ฌ๐Ÿ‡ง Englishengenglish
๐Ÿ‡ฌ๐Ÿ‡ง English, Middle (1100-1500)enm
Esperantoepo
๐Ÿ‡ช๐Ÿ‡ช Estonianest
๐Ÿ‡ซ๐Ÿ‡ด Faroesefao
๐Ÿ‡ต๐Ÿ‡ญ Filipinofil
๐Ÿ‡ซ๐Ÿ‡ฎ Finnishfinfinnish
๐Ÿ‡ซ๐Ÿ‡ท Frenchfrafrench
๐Ÿ‡ซ๐Ÿ‡ท French, Middle (ca. 1400-1600)frm
๐Ÿ‡ช๐Ÿ‡ธ Galicianglg
๐Ÿ‡ฌ๐Ÿ‡ช Georgiankat
๐Ÿ‡ฌ๐Ÿ‡ช Georgian - Oldkat_old
๐Ÿ‡ฉ๐Ÿ‡ช Germandeugerman
๐Ÿ‡ฉ๐Ÿ‡ช German - Frakturdeu_frak
๐Ÿ‡ฉ๐Ÿ‡ช German Frakturfrk
๐Ÿ‡ฌ๐Ÿ‡ท Greek, Ancientgrc
๐Ÿ‡ฌ๐Ÿ‡ท Greek, Modernell
๐Ÿ‡ฎ๐Ÿ‡ณ Gujaratiguj
๐Ÿ‡ญ๐Ÿ‡น Haitian; Haitian Creolehat
๐Ÿ‡ฎ๐Ÿ‡ฑ Hebrewheb
๐Ÿ‡ฎ๐Ÿ‡ณ Hindihin
๐Ÿ‡ญ๐Ÿ‡บ Hungarianhun
๐Ÿ‡ฎ๐Ÿ‡ธ Icelandicisl
๐Ÿ‡ฎ๐Ÿ‡ฉ Indonesianindindonesian
๐Ÿ‡จ๐Ÿ‡ฆ Inuktitutiku
๐Ÿ‡ฎ๐Ÿ‡ช Irishgle
๐Ÿ‡ฎ๐Ÿ‡น Italianitaitalian
๐Ÿ‡ฎ๐Ÿ‡น Italian - Oldita_old
๐Ÿ‡ฏ๐Ÿ‡ต Japanesejpn
๐Ÿ‡ฏ๐Ÿ‡ต Japanese (Vertical)jpn_vert
๐Ÿ‡ฎ๐Ÿ‡ฉ Javanesejav
๐Ÿ‡ฎ๐Ÿ‡ณ Kannadakan
๐Ÿ‡ฐ๐Ÿ‡ฟ Kazakhkaz
๐Ÿ‡ฐ๐Ÿ‡ฌ Kirghiz; Kyrgyzkir
๐Ÿ‡ฐ๐Ÿ‡ท Koreankor
๐Ÿ‡ฐ๐Ÿ‡ท Korean (Vertical)kor_vert
๐Ÿ‡ฎ๐Ÿ‡ถ Kurdishkur
๐Ÿ‡น๐Ÿ‡ท Kurmanji (Kurdish)kmr
๐Ÿ‡ฑ๐Ÿ‡ฆ Laolao
๐Ÿ‡ป๐Ÿ‡ฆ Latinlat
๐Ÿ‡ฑ๐Ÿ‡ป Latvianlav
๐Ÿ‡ฑ๐Ÿ‡น Lithuanianlit
๐Ÿ‡ฑ๐Ÿ‡บ Luxembourgishltz
๐Ÿ‡ฒ๐Ÿ‡ฐ Macedonianmkd
๐Ÿ‡ฒ๐Ÿ‡พ Malaymsamalay
๐Ÿ‡ฎ๐Ÿ‡ณ Malayalammal
๐Ÿ‡ฒ๐Ÿ‡น Maltesemlt
๐Ÿ‡ณ๐Ÿ‡ฟ Maorimri
๐Ÿ‡ฎ๐Ÿ‡ณ Marathimar
Math/Equation detectionequ
๐Ÿ‡ฒ๐Ÿ‡ณ Mongolianmon
๐Ÿ‡ณ๐Ÿ‡ต Nepalinep
๐Ÿ‡ณ๐Ÿ‡ด Norwegiannornorwegian
๐Ÿ‡ซ๐Ÿ‡ท Occitanoci
๐Ÿ‡ฎ๐Ÿ‡ณ Oriyaori
๐Ÿ‡ฎ๐Ÿ‡ณ Panjabi; Punjabipan
๐Ÿ‡ฎ๐Ÿ‡ท Persianfas
๐Ÿ‡ต๐Ÿ‡ฑ Polishpolpolish
๐Ÿ‡ต๐Ÿ‡น Portugueseporportuguese
๐Ÿ‡ฆ๐Ÿ‡ซ Pushto; Pashtopus
๐Ÿ‡ต๐Ÿ‡ช Quechuaque
๐Ÿ‡ท๐Ÿ‡ด Romanian; Moldavianron
๐Ÿ‡ท๐Ÿ‡บ Russianrus
๐Ÿ‡ฎ๐Ÿ‡ณ Sanskritsan
๐Ÿ‡ฌ๐Ÿ‡ง Scottish Gaelicgla
๐Ÿ‡ท๐Ÿ‡ธ Serbiansrpserbian
๐Ÿ‡ท๐Ÿ‡ธ Serbian - Latinsrp_latn
๐Ÿ‡ต๐Ÿ‡ฐ Sindhisnd
๐Ÿ‡ฑ๐Ÿ‡ฐ Sinhala; Sinhalesesin
๐Ÿ‡ธ๐Ÿ‡ฐ Slovakslkslovak
๐Ÿ‡ธ๐Ÿ‡ฐ Slovak - Frakturslk_frak
๐Ÿ‡ธ๐Ÿ‡ฎ Slovenianslvslovenian
๐Ÿ‡ช๐Ÿ‡ธ Spanish; Castilianspaspanish
๐Ÿ‡ช๐Ÿ‡ธ Spanish - Oldspa_old
๐Ÿ‡ฎ๐Ÿ‡ฉ Sundanesesun
๐Ÿ‡ฐ๐Ÿ‡ช Swahiliswa
๐Ÿ‡ธ๐Ÿ‡ช Swedishsweswedish
๐Ÿ‡ธ๐Ÿ‡พ Syriacsyr
๐Ÿ‡ต๐Ÿ‡ญ Tagalogtgl
๐Ÿ‡น๐Ÿ‡ฏ Tajiktgk
๐Ÿ‡ฎ๐Ÿ‡ณ Tamiltam
๐Ÿ‡ท๐Ÿ‡บ Tatartat
๐Ÿ‡ฎ๐Ÿ‡ณ Telugutel
๐Ÿ‡น๐Ÿ‡ญ Thaitha
๐Ÿ‡จ๐Ÿ‡ณ Tibetanbod
๐Ÿ‡ช๐Ÿ‡ท Tigrinyatir
๐Ÿ‡น๐Ÿ‡ด Tongaton
๐Ÿ‡น๐Ÿ‡ท Turkishturturkish
๐Ÿ‡จ๐Ÿ‡ณ Uighur; Uyghuruig
๐Ÿ‡บ๐Ÿ‡ฆ Ukrainianukr
๐Ÿ‡ต๐Ÿ‡ฐ Urduurd
๐Ÿ‡บ๐Ÿ‡ฟ Uzbekuzb
๐Ÿ‡บ๐Ÿ‡ฟ Uzbek - Cyrillicuzb_cyrl
๐Ÿ‡ป๐Ÿ‡ณ Vietnamesevie
๐Ÿ‡ฌ๐Ÿ‡ง Welshcym
๐Ÿ‡ณ๐Ÿ‡ฑ Western Frisianfry
๐Ÿ‡ฎ๐Ÿ‡ฑ Yiddishyid
๐Ÿ‡ณ๐Ÿ‡ฌ Yorubayor

Security is our top priority

No document storage

No input or resulting documents are stored on our infrastructure. All files are deleted as soon as a request finishes. Alternatively, check out our self-hosted product.

HTTPS encryption

All communication between your application and Nutrient is done via HTTPS to ensure your data is encrypted when itโ€™s sent to us.

Safe payment processing

All payments are handled by Paddle. Nutrient DWS Processor API never has direct access to any of your payment data.

Ready to try it?

Create an account to get your API key and start making API calls.