{"id":34822,"date":"2024-07-22T07:00:00","date_gmt":"2024-07-22T14:00:00","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=34822"},"modified":"2025-11-06T15:37:19","modified_gmt":"2025-11-06T23:37:19","slug":"building-image-to-text-api","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api","title":{"rendered":"Build an Image-to-Text API With Cloudinary for Free"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Building a convert-image-to-text API using Cloudinary for image storage and manipulation and an OCR (optical character recognition) service to extract text from images can be a powerful tool. In this blog post, in this way, we\u2019ll use OCR image to text API to create a simple image-to-text API that uploads images to Cloudinary, processes them to extract text, and returns them to the user.<\/p>\n<h2>Why is an Image-to Text API Useful?<\/h2>\n<p>Implementing an image-to-text API streamlines business operations and enhances user experiences across various sectors:<\/p>\n<ul>\n<li>\n<strong>Automated data entry<\/strong>. Reduce time and errors with manually inputting data from paperwork, such as invoices and receipts.<\/li>\n<li>\n<strong>Content accessibility<\/strong>. Convert text within images to accessible, searchable, and translatable text, aiding those with visual impairments and enhancing the digital user experience.<\/li>\n<li>\n<strong>Content management<\/strong>. Efficiently extract, catalog, and manage text from images, ideal for historical documents and educational materials.<\/li>\n<li>\n<strong>Data extraction and analysis<\/strong>. Extract data from visual sources for analysis, aiding researchers and analysts with documents, charts, and graphs.<\/li>\n<li>\n<strong>Security and compliance<\/strong>. Assist sectors such as banking and healthcare in anonymizing and redacting sensitive documentation, promoting data protection.<\/li>\n<li>\n<strong>Security measures<\/strong>. Particularly useful in security, the technology can automatically read vehicle plate numbers, aiding in traffic control, parking management, and law enforcement. It enhances security protocols by allowing for the quick identification of vehicles, monitoring of restricted areas, and automation of access control systems.\nLet\u2019s extract text from the receipt in the image below:<\/li>\n<\/ul>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img width=\"612\" height=\"612\" data-public-id=\"Web_Assets\/blog\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1.jpg\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/w_612,h_612,c_fill,g_auto\/f_auto,q_auto\/v1721671568\/Web_Assets\/blog\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1.jpg?_i=AA\" alt=\"Image showing a scan of a paper receipt to be used for the convert image to text api project\" class=\"wp-post-34822 wp-image-34823\" data-format=\"jpg\" data-transformations=\"f_auto,q_auto\" data-version=\"1721671568\" data-seo=\"1\" srcset=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1721671568\/Web_Assets\/blog\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1.jpg?_i=AA 612w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1721671568\/Web_Assets\/blog\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1.jpg?_i=AA 150w, https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1721671568\/Web_Assets\/blog\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1\/blog-Building-an-Image-to-Text-API-Using-Cloudinary-1.jpg?_i=AA 300w\" sizes=\"auto, (max-width: 612px) 100vw, 612px\" \/><figcaption class=\"wp-element-caption\">Register sale receipt isolated on white background. Cash receipt printed. Vector stock<\/figcaption><\/figure><\/div>\n\n<div class=\"wp-block-cloudinary-markdown \"><p>The goal is to upload the image to <a href=\"https:\/\/cloudinary.com\/\">Cloudinary<\/a> and extract the text from the image for bookkeeping or whatever use case. We\u2019ll create an image OCR API that uploads an image to Cloudinary and extracts the text content in the image using the OCR add-on available in Cloudinary.<\/p>\n<p>At the end of this blog post, our API should return the information below for the above image:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">{\n    <span class=\"hljs-attr\">\"imageUrl\"<\/span>: <span class=\"hljs-string\">\"\"<\/span>, <span class=\"hljs-comment\">\/\/ URL of the image in your Cloudinary account<\/span>\n    <span class=\"hljs-attr\">\"text\"<\/span>: <span class=\"hljs-string\">\"Address:\\nDate:\\nManager:\\nRECEIPT\\nCOMPANY NAME\\nLorem Ipsum 8\/24\\nMM\/DD\/YYYY\\nLorem Ipsum\\nDescription\\nOrange Juice\\nApples\\nTomato\\nFish\\nBeef\\nOnion\\nCheese\\nTax\\nTOTAL\\nTHANK YOU\\n123456778963578021\\nPrice\\n$2.15\\n$3.50\\n$2.40\\n$6.99\\n$10.00\\n$1.25\\n$3.40\\n$29.69\"<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h2>Prerequisites<\/h2>\n<p>You should have basic knowledge of Node.js and Express and the following tools set:<\/p>\n<ul>\n<li>\n<code>Node.js<\/code> and <code>npm<\/code> installed on your machine.<\/li>\n<li>\n<code>A Cloudinary account<\/code>. <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for free for life<\/a> if you haven\u2019t already.<\/li>\n<\/ul>\n<p>Before writing some code, make sure you\u2019re subscribed to the OCR text detection and extraction add-on. It includes a free plan for up to 50 image-to-text extractions.\nIf you\u2019re subscribed to this add-on, you can skip this part.<\/p>\n<p>Log in to your Cloudinary account, go to Settings, click Add-ons, search for OCR Text Detection and Extraction add-on, and subscribe to it.<\/p>\n<h2>Installation and Configuration<\/h2>\n<p>We\u2019ll use TypeScript, Cloudinary for image storage, and Cloudinary\u2019s OCR Text Detection and Extraction Add-on for text extraction.<\/p>\n<p>Create a new directory for your project and initialize a Node.js project:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">mkdir image_to_text_api\ncd image_to_text_api\nnpm init -y\n<\/code><\/span><\/pre>\n<p>The above command creates a directory called <code>image_to_text_api<\/code>, navigates to the directory, and creates a package.json file.<\/p>\n<h3>Installing Dependencies<\/h3>\n<p>Now that we have <code>package.json<\/code> file, let\u2019s install all the dependencies we\u2019ll use for the project by running the command below:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npm install express multer cloudinary dotenv\n<\/code><\/span><\/pre>\n<p>Since this is a TypeScript project, we must also install TypeScript and the type definitions for the packages we installed above. To do so, run the following command:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">npm<\/span> <span class=\"hljs-selector-tag\">install<\/span> <span class=\"hljs-selector-tag\">-D<\/span> <span class=\"hljs-keyword\">@types<\/span>\/express @types\/multer @types\/node typescript\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Configuring TypeScript<\/h3>\n<p>Now, let\u2019s configure Typescript for our project. Create a <code>tsconfig.json<\/code> file in your project root with the following TypeScript configuration:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">{\n  <span class=\"hljs-attr\">\"compilerOptions\"<\/span>: {\n    <span class=\"hljs-attr\">\"target\"<\/span>: <span class=\"hljs-string\">\"es6\"<\/span>,\n    <span class=\"hljs-attr\">\"module\"<\/span>: <span class=\"hljs-string\">\"commonjs\"<\/span>,\n    <span class=\"hljs-attr\">\"rootDir\"<\/span>: <span class=\"hljs-string\">\".\/\"<\/span>,\n    <span class=\"hljs-attr\">\"outDir\"<\/span>: <span class=\"hljs-string\">\".\/dist\"<\/span>,\n    <span class=\"hljs-attr\">\"esModuleInterop\"<\/span>: <span class=\"hljs-literal\">true<\/span>,\n    <span class=\"hljs-attr\">\"strict\"<\/span>: <span class=\"hljs-literal\">true<\/span>\n  },\n  <span class=\"hljs-attr\">\"include\"<\/span>: &#91;<span class=\"hljs-string\">\".\/src\/**\/*\"<\/span>],\n  <span class=\"hljs-attr\">\"exclude\"<\/span>: &#91;<span class=\"hljs-string\">\"node_modules\"<\/span>]\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Set Up Your Environment Variables<\/h3>\n<p>Create a <code>.env<\/code> file to store your Cloudinary credentials and API configuration:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">CLOUDINARY_CLOUD_NAME=<span class=\"hljs-string\">'your_cloud_name'<\/span>\nCLOUDINARY_API_KEY=<span class=\"hljs-string\">'your_api_key'<\/span>\nCLOUDINARY_API_SECRET=<span class=\"hljs-string\">'your_api_secret\u2019\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Replace the placeholders with your actual Cloudinary details. You can find this on your dashboard when you log in to Cloudinary.<\/p>\n<p><strong>Note: Never expose your <code>.env<\/code> file\u2019s contents or commit it to version control systems.<\/strong><\/p>\n<h3>Building the API<\/h3>\n<p>Let\u2019s set up a simple server using Express.js.\n<a href=\"https:\/\/expressjs.com\/\">Express.js<\/a> is a minimal and flexible Node.js web application framework that provides robust features for building APIs.<\/p>\n<p>We\u2019ll also use the <code>dotenv<\/code> package to help load environmental variables from <code>.env<\/code> files.<\/p>\n<p>Inside your project directory, create a <code>src<\/code> folder. Add an <code>index.ts<\/code> file with the following code:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Import the required modules from the installed packages<\/span>\n<span class=\"hljs-keyword\">import<\/span> express <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'express'<\/span>; <span class=\"hljs-comment\">\/\/ Express.js framework for building the API<\/span>\n<span class=\"hljs-keyword\">import<\/span> dotenv <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'dotenv'<\/span>; <span class=\"hljs-comment\">\/\/ Dotenv for loading environment variables from .env file<\/span>\n\n<span class=\"hljs-comment\">\/\/ Load environment variables from .env file to process.env<\/span>\ndotenv.config();\n\n<span class=\"hljs-comment\">\/\/ Initialize the Express.js application<\/span>\n<span class=\"hljs-keyword\">const<\/span> app = express();\n<span class=\"hljs-comment\">\/\/ Define the port to run the server on; default to 3000 if not specified in .env<\/span>\n<span class=\"hljs-keyword\">const<\/span> PORT = process.env.PORT || <span class=\"hljs-number\">3000<\/span>;\n\n<span class=\"hljs-comment\">\/\/ A simple GET route to verify our server is running by returning a 'Hello world' message<\/span>\napp.get(<span class=\"hljs-string\">'\/'<\/span>, (req, res) =&gt; {\n   res.send(<span class=\"hljs-string\">\"Hello world\"<\/span>);\n});\n\n<span class=\"hljs-comment\">\/\/ Start the Express server on the defined port<\/span>\napp.listen(PORT, () =&gt; {\n  <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Server running on port <span class=\"hljs-subst\">${PORT}<\/span>`<\/span>);\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Cloudinary Configuration<\/h3>\n<p>Now that we have a server set up, let\u2019s configure Cloudinary. Add the following line of code to your index.ts file:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">import { v2 <span class=\"hljs-keyword\">as<\/span> cloudinary } from <span class=\"hljs-string\">'cloudinary'<\/span>;\n<span class=\"hljs-comment\">\/\/\u2026<\/span>\n\n<span class=\"hljs-comment\">\/\/ Load environment variables from .env file to process.env<\/span>\ndotenv.config();\n\n<span class=\"hljs-comment\">\/\/ Configure Cloudinary with your account details from environment variables<\/span>\ncloudinary.config({ \n  cloud_name: process.env.CLOUDINARY_CLOUD_NAME, <span class=\"hljs-comment\">\/\/ Your Cloudinary cloud name<\/span>\n  api_key: process.env.CLOUDINARY_API_KEY, <span class=\"hljs-comment\">\/\/ Your Cloudinary API key<\/span>\n  api_secret: process.env.CLOUDINARY_API_SECRET, <span class=\"hljs-comment\">\/\/ Your Cloudinary API secret<\/span>\n  secure: <span class=\"hljs-keyword\">true<\/span> <span class=\"hljs-comment\">\/\/ Ensures that the connection to Cloudinary is secure<\/span>\n});\n\n<span class=\"hljs-comment\">\/\/\u2026<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the above code, we imported Cloudinary and configured it, passing the cloud name, API key, and API secret from our <code>.env<\/code> file.<\/p>\n<p>We can now create an endpoint that receives an image, passes the image to the Cloudinary API to be uploaded, and returns, among other things, the image URL and extracted text from the image.<\/p>\n<p>Add <code>import multer from 'multer'<\/code> at the top of the file and add the rest of the below code after the get route:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> multer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'multer'<\/span>; <span class=\"hljs-comment\">\/\/ Multer for handling multipart\/form-data (for file upload)<\/span>\n<span class=\"hljs-comment\">\/\/\u2026<\/span>\n\n<span class=\"hljs-comment\">\/\/ Initialize multer, a middleware for handling file uploads<\/span>\n<span class=\"hljs-keyword\">const<\/span> upload = multer();\n\n<span class=\"hljs-comment\">\/\/ Define a POST route for uploading images<\/span>\napp.post(<span class=\"hljs-string\">'\/upload'<\/span>, upload.single(<span class=\"hljs-string\">'file'<\/span>), (req, res) =&gt; {\n  <span class=\"hljs-comment\">\/\/ Check if a file is provided in the request<\/span>\n  <span class=\"hljs-keyword\">if<\/span> (!req.file) {\n    <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">400<\/span>).send(<span class=\"hljs-string\">'No file uploaded.'<\/span>); <span class=\"hljs-comment\">\/\/ Return an error if no file is uploaded<\/span>\n  }\n\n  <span class=\"hljs-comment\">\/\/ Use Cloudinary's upload_stream method to upload the file directly from a stream<\/span>\n  cloudinary.uploader.upload_stream({ <span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-attr\">ocr<\/span>: <span class=\"hljs-string\">\"adv_ocr\"<\/span> }, (error, result) =&gt; {\n    <span class=\"hljs-keyword\">if<\/span> (error || !result) {\n      <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">500<\/span>).send(<span class=\"hljs-string\">'Failed to upload image or extract text.'<\/span>); <span class=\"hljs-comment\">\/\/ Return an error if upload fails<\/span>\n    }\n\n    <span class=\"hljs-comment\">\/\/ On success, return the URL of the uploaded image and the extracted text<\/span>\n    res.json({ <span class=\"hljs-attr\">imageUrl<\/span>: result.secure_url, <span class=\"hljs-attr\">text<\/span>: result.info.ocr.adv_ocr.data&#91;<span class=\"hljs-number\">0<\/span>].textAnnotations&#91;<span class=\"hljs-number\">0<\/span>].description });\n  }).end(req.file.buffer); <span class=\"hljs-comment\">\/\/ End the stream by passing the file buffer<\/span>\n});\n<span class=\"hljs-comment\">\/\/\u2026<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In the setup where we initialize <code>multer<\/code>, we\u2019re preparing our application to handle file uploads. Multer is a middleware for Express.js designed to process multipart\/form-data, which is the content type used when forms are submitted with files. When we call <code>upload.single('file')<\/code>, we\u2019re configuring <code>multer<\/code> to accept a single file with the form field name \u2018file\u2019. In the incoming request, <code>multer<\/code> looks for a field named <code>'file'<\/code> and processes the uploaded file accordingly, making it available in <code>req.file<\/code>. This setup is crucial for our API, allowing users to upload images for text extraction without complications.<\/p>\n<p>After setting up <code>multer<\/code>, we\u2019ll dive into Cloudinary\u2019s <code>upload_stream<\/code> method in the <code>\/upload<\/code> route handler. This method is part of Cloudinary\u2019s powerful image management and processing capabilities, specifically designed for uploading images directly from a stream, which, in our case, comes from the uploaded file\u2019s buffer. Let\u2019s break down the parameters we used for our OCR image to text API:<\/p>\n<ul>\n<li>\n<p><code>resource_type: 'image'<\/code>. This parameter specifies the type of resource we\u2019re uploading. Since our API focuses on images, we\u2019ll set this to \u2018image\u2019. Cloudinary supports various resource types, but for our purpose of extracting text from images, specifying the resource type as \u201cimage\u201d ensures that Cloudinary processes our upload correctly and applies any image-specific optimizations or transformations.<\/p>\n<\/li>\n<li>\n<p><code>ocr: &quot;adv_ocr&quot;<\/code>. The OCR parameter is where the magic of text extraction happens. By setting this to \u201cadv_ocr\u201d, we\u2019re instructing Cloudinary to use its advanced OCR capabilities to detect and extract text from the uploaded image. This parameter can be fine-tuned further depending on the content of your images. For example, <code>ocr: &quot;adv_ocr:document&quot;<\/code> could be used for text-heavy images like scanned documents to optimize text extraction.<\/p>\n<\/li>\n<\/ul>\n<p>In our code, if the upload and text extraction succeeds, we\u2019ll return the URL of the uploaded image (<code>result.secure_url<\/code>) and the extracted text (<code>result.info.ocr.adv_ocr.data[0].textAnnotations[0].description<\/code>) in our response.<\/p>\n<p>This process showcases how seamlessly Cloudinary integrates image uploading with advanced features like OCR, enabling developers to build sophisticated image-to-text conversion APIs with minimal effort.<\/p>\n<p>Below is the full code implementation:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Import the required modules from the installed packages<\/span>\n<span class=\"hljs-keyword\">import<\/span> express <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'express'<\/span>; <span class=\"hljs-comment\">\/\/ Express.js framework for building the API<\/span>\n<span class=\"hljs-keyword\">import<\/span> dotenv <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'dotenv'<\/span>; <span class=\"hljs-comment\">\/\/ Dotenv for loading environment variables from .env file<\/span>\n<span class=\"hljs-keyword\">import<\/span> multer <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'multer'<\/span>; <span class=\"hljs-comment\">\/\/ Multer for handling multipart\/form-data (for file upload)<\/span>\n<span class=\"hljs-keyword\">import<\/span> { v2 <span class=\"hljs-keyword\">as<\/span> cloudinary } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'cloudinary'<\/span>; <span class=\"hljs-comment\">\/\/ Cloudinary SDK for image storage and manipulation<\/span>\n\n<span class=\"hljs-comment\">\/\/ Load environment variables from .env file to process.env<\/span>\ndotenv.config();\n\n<span class=\"hljs-comment\">\/\/ Initialize the Express.js application<\/span>\n<span class=\"hljs-keyword\">const<\/span> app = express();\n<span class=\"hljs-comment\">\/\/ Define the port to run the server on; default to 3000 if not specified in .env<\/span>\n<span class=\"hljs-keyword\">const<\/span> PORT = process.env.PORT || <span class=\"hljs-number\">3000<\/span>;\n<span class=\"hljs-comment\">\/\/ Initialize multer, a middleware for handling file uploads<\/span>\n<span class=\"hljs-keyword\">const<\/span> upload = multer();\n\n<span class=\"hljs-comment\">\/\/ Configure Cloudinary with your account details from environment variables<\/span>\ncloudinary.config({ \n  <span class=\"hljs-attr\">cloud_name<\/span>: process.env.CLOUDINARY_CLOUD_NAME, <span class=\"hljs-comment\">\/\/ Your Cloudinary cloud name<\/span>\n  <span class=\"hljs-attr\">api_key<\/span>: process.env.CLOUDINARY_API_KEY, <span class=\"hljs-comment\">\/\/ Your Cloudinary API key<\/span>\n  <span class=\"hljs-attr\">api_secret<\/span>: process.env.CLOUDINARY_API_SECRET, <span class=\"hljs-comment\">\/\/ Your Cloudinary API secret<\/span>\n  <span class=\"hljs-attr\">secure<\/span>: <span class=\"hljs-literal\">true<\/span> <span class=\"hljs-comment\">\/\/ Ensures that the connection to Cloudinary is secure<\/span>\n});\n\n<span class=\"hljs-comment\">\/\/ A simple GET route to verify our server is running by returning a 'Hello world' message<\/span>\napp.get(<span class=\"hljs-string\">'\/'<\/span>, (req, res) =&gt; {\n   res.send(<span class=\"hljs-string\">\"Hello world\"<\/span>);\n});\n\n<span class=\"hljs-comment\">\/\/ Define a POST route for uploading images<\/span>\napp.post(<span class=\"hljs-string\">'\/upload'<\/span>, upload.single(<span class=\"hljs-string\">'file'<\/span>), (req, res) =&gt; {\n  <span class=\"hljs-comment\">\/\/ Check if a file is provided in the request<\/span>\n  <span class=\"hljs-keyword\">if<\/span> (!req.file) {\n    <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">400<\/span>).send(<span class=\"hljs-string\">'No file uploaded.'<\/span>); <span class=\"hljs-comment\">\/\/ Return an error if no file is uploaded<\/span>\n  }\n\n  <span class=\"hljs-comment\">\/\/ Use Cloudinary's upload_stream method to upload the file directly from a stream<\/span>\n  cloudinary.uploader.upload_stream({ <span class=\"hljs-attr\">resource_type<\/span>: <span class=\"hljs-string\">'image'<\/span>, <span class=\"hljs-attr\">ocr<\/span>: <span class=\"hljs-string\">\"adv_ocr\"<\/span> }, (error, result) =&gt; {\n    <span class=\"hljs-keyword\">if<\/span> (error || !result) {\n      <span class=\"hljs-keyword\">return<\/span> res.status(<span class=\"hljs-number\">500<\/span>).send(<span class=\"hljs-string\">'Failed to upload image or extract text.'<\/span>); <span class=\"hljs-comment\">\/\/ Return an error if upload fails<\/span>\n    }\n\n    <span class=\"hljs-comment\">\/\/ On success, return the URL of the uploaded image and the extracted text<\/span>\n    res.json({ <span class=\"hljs-attr\">imageUrl<\/span>: result.secure_url, <span class=\"hljs-attr\">text<\/span>: result.info.ocr.adv_ocr.data&#91;<span class=\"hljs-number\">0<\/span>].textAnnotations&#91;<span class=\"hljs-number\">0<\/span>].description });\n  }).end(req.file.buffer); <span class=\"hljs-comment\">\/\/ End the stream by passing the file buffer<\/span>\n});\n\n<span class=\"hljs-comment\">\/\/ Start the Express server on the defined port<\/span>\napp.listen(PORT, () =&gt; {\n  <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Server running on port <span class=\"hljs-subst\">${PORT}<\/span>`<\/span>);\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>To start the server, you need to compile the TypeScript code by running the following command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">tsc\n<\/code><\/span><\/pre>\n<p>Now start the server by running the command:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">node dist\/src\/index.js\n<\/code><\/span><\/pre>\n<p>If you have <code>ts-node<\/code> installed globally on your machine, you can easily run your TypeScript file directly using <code>ts-node<\/code> without needing to compile it:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">ts-node src\/index.ts\n<\/code><\/span><\/pre>\n<h2>Testing Your API<\/h2>\n<p>To test your API, use a tool like Postman or CURL to send a POST request with a file to <code>http:\/\/localhost:3000\/upload<\/code>.\nIf you followed the instructions in this article, you should see a response that looks like this:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json shcb-wrap-lines\">{\n    <span class=\"hljs-attr\">\"imageUrl\"<\/span>: <span class=\"hljs-string\">\"uploaded_image_url_from_cloudinary\"<\/span>,\n    <span class=\"hljs-attr\">\"text\"<\/span>: <span class=\"hljs-string\">\"text_extracted_from_the_image_uploaded\"<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h2>Conclusion<\/h2>\n<p>In this blog post, we\u2019ve demonstrated how to build a robust Image-to-text API using TypeScript, Cloudinary, and its OCR Text Detection and Extraction add-on. This solution showcases the power of leveraging Cloudinary\u2019s comprehensive image management capabilities alongside advanced OCR technology to extract text from images efficiently. By integrating these technologies, we\u2019ve created an API that simplifies extracting images from text, offering a streamlined solution for applications requiring OCR functionality.<\/p>\n<p>Opting for Cloudinary\u2019s OCR add-on over external OCR image to text API libraries simplifies the development process, reduces the need for additional dependencies, and allows for seamless scaling. This approach enhances performance and ensures consistency and reliability across different environments. By utilizing Cloudinary\u2019s cloud-based platform, developers can benefit from robust image storage, optimization, and transformation capabilities, making this solution ideal for a wide range of use cases, from content management systems to automated data entry applications. <a href=\"https:\/\/cloudinary.com\/\">Sign up<\/a> for free today.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":87,"featured_media":34825,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[337,332],"class_list":["post-34822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-accessibility","tag-api"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Build an Image-to-Text API With Cloudinary for Free<\/title>\n<meta name=\"description\" content=\"Create a simple image to text API that uses Cloudinary and OCR to convert images to text.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build an Image-to-Text API With Cloudinary for Free\" \/>\n<meta property=\"og:description\" content=\"Create a simple image to text API that uses Cloudinary and OCR to convert images to text.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-07-22T14:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-06T23:37:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"melindapham\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\"},\"author\":{\"name\":\"melindapham\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\"},\"headline\":\"Build an Image-to-Text API With Cloudinary for Free\",\"datePublished\":\"2024-07-22T14:00:00+00:00\",\"dateModified\":\"2025-11-06T23:37:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\"},\"wordCount\":20,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA\",\"keywords\":[\"Accessibility\",\"API\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2024\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\",\"url\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\",\"name\":\"Build an Image-to-Text API With Cloudinary for Free\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA\",\"datePublished\":\"2024-07-22T14:00:00+00:00\",\"dateModified\":\"2025-11-06T23:37:19+00:00\",\"description\":\"Create a simple image to text API that uses Cloudinary and OCR to convert images to text.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA\",\"width\":2000,\"height\":1100,\"caption\":\"Image showing a scan of a paper receipt and code used for the convert image to text api project\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build an Image-to-Text API With Cloudinary for Free\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9\",\"name\":\"melindapham\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g\",\"caption\":\"melindapham\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Build an Image-to-Text API With Cloudinary for Free","description":"Create a simple image to text API that uses Cloudinary and OCR to convert images to text.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api","og_locale":"en_US","og_type":"article","og_title":"Build an Image-to-Text API With Cloudinary for Free","og_description":"Create a simple image to text API that uses Cloudinary and OCR to convert images to text.","og_url":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api","og_site_name":"Cloudinary Blog","article_published_time":"2024-07-22T14:00:00+00:00","article_modified_time":"2025-11-06T23:37:19+00:00","og_image":[{"width":2000,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA","type":"image\/jpeg"}],"author":"melindapham","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api"},"author":{"name":"melindapham","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9"},"headline":"Build an Image-to-Text API With Cloudinary for Free","datePublished":"2024-07-22T14:00:00+00:00","dateModified":"2025-11-06T23:37:19+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api"},"wordCount":20,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA","keywords":["Accessibility","API"],"inLanguage":"en-US","copyrightYear":"2024","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api","url":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api","name":"Build an Image-to-Text API With Cloudinary for Free","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA","datePublished":"2024-07-22T14:00:00+00:00","dateModified":"2025-11-06T23:37:19+00:00","description":"Create a simple image to text API that uses Cloudinary and OCR to convert images to text.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/building-image-to-text-api"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA","width":2000,"height":1100,"caption":"Image showing a scan of a paper receipt and code used for the convert image to text api project"},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/building-image-to-text-api#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Build an Image-to-Text API With Cloudinary for Free"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/0d5ad601e4c3b5be89245dfb14be42d9","name":"melindapham","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e6f989fa97fe94be61596259d8629c3df65aec4c7da5c0000f90d810f313d4f4?s=96&d=mm&r=g","caption":"melindapham"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1714772391\/image_to_text-blog\/image_to_text-blog.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=34822"}],"version-history":[{"count":3,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34822\/revisions"}],"predecessor-version":[{"id":39133,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/34822\/revisions\/39133"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/34825"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=34822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=34822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=34822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}