{"id":12012,"date":"2025-10-02T16:40:21","date_gmt":"2025-10-02T07:40:21","guid":{"rendered":"https:\/\/sreake.com\/?p=12012"},"modified":"2026-02-10T16:15:09","modified_gmt":"2026-02-10T07:15:09","slug":"make-llm-output-stable-by-instructor-2","status":"publish","type":"post","link":"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/","title":{"rendered":"Want Stable, Structured LLM Outputs? Try Instructor!"},"content":{"rendered":"\n<p><em><em>This blog post is a translation of\u00a0<a href=\"https:\/\/sreake.com\/blog\/make-llm-output-stable-by-instructor\/\" title=\"\">a Japanese article<\/a>\u00a0posted on September 29th, 2025.<\/em><\/em><\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_75 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#Introduction_The_Challenge_of_Controlling_LLM_Output\" >Introduction: The Challenge of Controlling LLM Output<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#What_is_instructor-js\" >What is instructor-js?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#A_Practical_Example_Fetching_Hot_Spring_Recommendations\" >A Practical Example: Fetching Hot Spring Recommendations<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#1_Setup_Installing_and_Configuring_the_Library\" >1. Setup: Installing and Configuring the Library<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#2_Type_Definition_Defining_the_Desired_Response_Shape_with_Zod\" >2. Type Definition: Defining the Desired Response Shape with Zod<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#3_Execution_Calling_the_API_with_instructor\" >3. Execution: Calling the API with instructor<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#The_True_Power_of_instructor_The_Automatic_Retry_Feature\" >The True Power of instructor: The Automatic Retry Feature<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/sreake.com\/en\/blog\/make-llm-output-stable-by-instructor-2\/#Reference_Links\" >Reference Links<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction_The_Challenge_of_Controlling_LLM_Output\"><\/span>Introduction: The Challenge of Controlling LLM Output<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Have you ever thought something like this when developing an AI app?<\/p>\n\n\n\n<p>In developing applications using generative AI, I&#8217;ve found that one of the key challenges is consistently obtaining structured data from LLMs.<\/p>\n\n\n\n<p>Traditionally, even if you prompted the AI to \u201cplease respond in JSON format\u201d, the response you got back wasn&#8217;t always what you expected.<\/p>\n\n\n\n<p><strong>Some common problems:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A string that should end with <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">\"description\": \"Good for your skin\"<\/span><\/span><\/code> ends with <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">...Good for your skin\",<\/span><\/span><\/code> with an extra comma.<\/li><li>A required key (e.g. <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">rating<\/span><\/span><\/code> ) is missing.<\/li><li>Getting a string (<code><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\"><span style=\"color:#ef7133\" class=\"tadv-color\">\"5\"<\/span><\/span><\/code>) where we would expect a number (<code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">5<\/span><\/span><\/code>)<\/li><\/ul>\n\n\n\n<p>To handle these incomplete responses, a lot of error-handling code was necessary. I&#8217;m sure many of you have struggled with handling edge cases like &#8220;What if this key is missing?&#8221; or &#8220;What if parsing fails?&#8221;<\/p>\n\n\n\n<p>That&#8217;s where <strong><code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor-js<\/span><\/span><\/code><\/strong> comes in. Today, I&#8217;ll introduce this library that allows you to handle LLM outputs in a type-safe manner using TypeScript and Zod. This library makes it easy to get structured and reliable responses.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_instructor-js\"><\/span>What is <code>instructor-js<\/code>?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In short, <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor-js<\/span><\/span><\/code> is <strong>a library that ensures the OpenAI API response conforms to the type you define with Zod.<\/strong><\/p>\n\n\n\n<p>The magic behind it lies in OpenAI&#8217;s <strong>Tool Calling feature<\/strong>. <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code> converts the schema we define with Zod into the Tool Calling format and instructs the LLM, &#8220;Please use this tool (schema) to answer.&#8221; This forces the LLM to follow the specified structure, and as a result, we can reliably get the data in the format we want.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Practical_Example_Fetching_Hot_Spring_Recommendations\"><\/span>A Practical Example: Fetching Hot Spring Recommendations<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Seeing is believing. Let&#8217;s use <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code> to ask an LLM, &#8220;Give me three recommendations for hot springs&#8221; and receive that information in a clean array.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Setup_Installing_and_Configuring_the_Library\"><\/span>1. Setup: Installing and Configuring the Library<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>First, let&#8217;s install the necessary libraries.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>npm install openai zod instructor-js<\/code><\/pre>\n\n\n\n<p>Next, initialize the OpenAI client and &#8220;patch&#8221; it with <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code> to extend it (this is the standard way of using <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code>).<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>import OpenAI from \"openai\";\nimport Instructor from \"instructor-js\";\n\n\/\/ Initialize the standard OpenAI client\nconst openai = new OpenAI({\n  apiKey: process.env.OPENAI_API_KEY,\n});\n\n\/\/ Extend the client with instructor!\nexport const instructor = Instructor({\n  client: openai,\n  mode: \"TOOLS\", \/\/ Specify Tool Calling mode\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"2_Type_Definition_Defining_the_Desired_Response_Shape_with_Zod\"><\/span>2. Type Definition: Defining the Desired Response Shape with Zod<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Next, we define the type of data we want the LLM to return using Zod. This time, we&#8217;ll define a type for individual hot spring information and a type for the overall response that contains an array of them.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>import { z } from \"zod\";\n\n\/\/ Schema for a single hot spring's information\nconst OnsenSchema = z.object({\n  name: z.string().describe(\"The name of the hot spring\"),\n  prefecture: z.string().describe(\"The prefecture where the hot spring is located\"),\n  features: z\n    .array(z.string())\n    .describe(\"An array of short keywords describing the features of the hot spring\"),\n  rating: z\n    .number()\n    .min(1)\n    .max(5)\n    .describe(\"A recommendation rating from 1 to 5\"),\n});\n\n\/\/ Schema for the entire response\nexport const OnsenResponseSchema = z.object({\n  onsenList: z.array(OnsenSchema).describe(\"A list of recommended hot springs\"),\n});\n\n\/\/ We can also infer the TypeScript type\nexport type OnsenResponse = z.infer&lt;typeof OnsenResponseSchema&gt;;<\/code><\/pre>\n\n\n\n<p>By adding <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">.describe()<\/span><\/span><\/code>, we help the LLM better understand the meaning of each field, making it more likely to generate the expected data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_Execution_Calling_the_API_with_instructor\"><\/span>3. Execution: Calling the API with <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code><span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>We&#8217;re all set. Let&#8217;s actually call the API using <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>import { instructor } from \".\/lib\/openai\";\nimport { OnsenResponseSchema, OnsenResponse } from \".\/schemas\";\n\nasync function getOnsenRecommendations(): Promise&lt;OnsenResponse&gt; {\n  console.log(\"Fetching recommended hot spring information...\");\n\n  const response = await instructor.chat.completions.create({\n    model: \"gpt-4o\",\n    messages: &#91;\n      {\n        role: \"user\",\n        content: \"Please give me three recommendations for hot springs.\",\n      },\n    ],\n    response_model: {\n      schema: OnsenResponseSchema,\n      name: \"OnsenRecommendations\",\n    },\n    max_retries: 3, \/\/ This is important!\n  });\n\n  return response;\n}\n\ngetOnsenRecommendations().then((data) =&gt; {\n  console.log(\"Successfully fetched!\");\n  console.log(JSON.stringify(data, null, 2));\n\n  \/\/ The type is guaranteed, so we can access properties directly!\n  console.log(\"\\\\\\\\n--- Recommendation #1 ---\");\n  console.log(`Name: ${data.onsenList&#91;0].name}`);\n  console.log(`Location: ${data.onsenList&#91;0].prefecture}`);\n  console.log(`Rating: \u2605${data.onsenList&#91;0].rating}`);\n});<\/code><\/pre>\n\n\n\n<p>All you need to do is specify the Zod schema you defined earlier in <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">response_model<\/span><\/span><\/code> and set <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">max_retries<\/span><\/span><\/code>.<\/p>\n\n\n\n<p><strong>Example of execution result:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code code-block\"><code>{\n  \"onsenList\": &#91;\n    {\n      \"name\": \"Hakone Yuryo\",\n      \"prefecture\": \"Kanagawa Prefecture\",\n      \"features\": &#91;\n        \"Available for day trips\",\n        \"Old folk house-style atmosphere\",\n        \"19 private open-air baths for rent\"\n      ],\n      \"rating\": 5\n    },\n    {\n      \"name\": \"Tenzan Tohji-kyo\",\n      \"prefecture\": \"Kanagawa Prefecture\",\n      \"features\": &#91;\n        \"Rustic open-air baths\",\n        \"Free-flowing spring water from its own source\",\n        \"Ample rest areas\"\n      ],\n      \"rating\": 4\n    },\n    {\n      \"name\": \"Ryuguden Honkan\",\n      \"prefecture\": \"Kanagawa Prefecture\",\n      \"features\": &#91;\n        \"Spectacular views of Lake Ashi and Mt. Fuji\",\n        \"Registered Tangible Cultural Property of Japan\",\n        \"Day-trip bathing plans available\"\n      ],\n      \"rating\": 5\n    }\n  ]\n}\n\n--- Recommendation #1 ---\nName: Hakone Yuryo\nLocation: Kanagawa Prefecture\nRating: \u26055<\/code><\/pre>\n\n\n\n<p>Look at that! We were able to get a perfectly typed object without writing any type conversion or parsing code. The developer experience is great, with editor autocompletion working for things like <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">data.onsenList[0].name<\/span><\/span><\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_True_Power_of_instructor_The_Automatic_Retry_Feature\"><\/span>The True Power of <code><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\"><span style=\"color:#ef7133\" class=\"tadv-color\">instructor<\/span><\/span><\/code>: The Automatic Retry Feature<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>I believe the true value of this library goes beyond simple type conversion.<\/p>\n\n\n\n<p>What&#8217;s particularly noteworthy is the <strong>automatic retry feature<\/strong> set with <code><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\"><span style=\"color:#ef7133\" class=\"tadv-color\">max_retries<\/span><\/span><\/code>. This is not just a simple re-execution.<\/p>\n\n\n\n<p>Suppose the LLM forgets the <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">rating<\/span><\/span><\/code> field on the first attempt. Then&#8230;<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code> receives the response.<\/li><li>Zod throws a validation error saying, &#8220;The <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">rating<\/span><\/span><\/code> field is required but does not exist!&#8221;<\/li><li><code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code> catches that error.<\/li><li><code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor<\/span><\/span><\/code> automatically sends a second request to the LLM with an additional instruction: <strong>&#8220;The previous response failed with this error. Next time, be sure to include <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">rating<\/span><\/span><\/code> in your response.&#8221;<\/strong><\/li><\/ol>\n\n\n\n<p>This Self-Correction loop frees developers from implementing complex validation. The code remains clean, and the system&#8217;s reliability improves.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor-js<\/span><\/span><\/code> is a powerful library that transforms the &#8220;uncertain&#8221; responses from an LLM into &#8220;certain, typed data.&#8221;<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Type Safety<\/strong>: Ensures type safety at both compile-time and runtime with Zod schemas.<\/li><li><strong>Automatic Retries<\/strong>: Achieves reliable output with its self-correction feature on failure.<\/li><li><strong>Development Efficiency<\/strong>: Eliminates the need for complex error handling, allowing you to focus on business logic.<\/li><\/ul>\n\n\n\n<p><strong>Some key benefits:<\/strong><\/p>\n\n\n\n<p>If you&#8217;re facing challenges with obtaining structured data in your LLM-powered development, I highly recommend giving <code><span style=\"color:#ef7133\" class=\"tadv-color\"><span style=\"background-color:#e9edf1\" class=\"tadv-background-color\">instructor-js<\/span><\/span><\/code> a try. it will significantly improve your development experience.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Reference_Links\"><\/span>Reference Links<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/567-labs\/instructor\">Instructor GitHub<\/a><\/li><li><a href=\"https:\/\/zod.dev\/\">Zod Documentation<\/a><\/li><li><a href=\"https:\/\/platform.openai.com\/docs\">OpenAI API Documentation<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hi from the Sreake team! Learn what Instructor is, and how you can use it to get stable, structured outputs from your LLM models.<\/p>\n","protected":false},"author":45,"featured_media":12013,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_locale":"en_US","_original_post":"https:\/\/sreake.com\/?p=11877","footnotes":""},"categories":[17],"tags":[23],"class_list":["post-12012","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-enginner-blog","en-US"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12012","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/users\/45"}],"replies":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/comments?post=12012"}],"version-history":[{"count":1,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12012\/revisions"}],"predecessor-version":[{"id":13493,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/posts\/12012\/revisions\/13493"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/media\/12013"}],"wp:attachment":[{"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/media?parent=12012"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/categories?post=12012"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sreake.com\/wp-json\/wp\/v2\/tags?post=12012"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}