{"id":1025,"date":"2026-07-02T06:43:20","date_gmt":"2026-07-01T23:43:20","guid":{"rendered":"https:\/\/sumberlaba.com\/index.php\/2026\/07\/02\/how-to-build-a-resume-parser-a-comprehensive-step-by-step-guide-for-developers\/"},"modified":"2026-07-02T06:43:20","modified_gmt":"2026-07-01T23:43:20","slug":"how-to-build-a-resume-parser-a-comprehensive-step-by-step-guide-for-developers","status":"publish","type":"post","link":"https:\/\/sumberlaba.com\/index.php\/2026\/07\/02\/how-to-build-a-resume-parser-a-comprehensive-step-by-step-guide-for-developers\/","title":{"rendered":"How to Build a Resume Parser: A Comprehensive Step-by-Step Guide for Developers"},"content":{"rendered":"<h1>How to Build a Resume Parser: A Comprehensive Step-by-Step Guide for Developers<\/h1>\n<p>Building a resume parser is one of the most common yet challenging tasks in the realm of human resources technology and natural language processing. A resume parser extracts structured data\u2014such as contact details, education, work experience, skills, and certifications\u2014from unstructured or semi-structured resume documents (PDF, DOCX, TXT, etc.). Whether you are building an applicant tracking system (ATS), a job matching platform, or a simple skill extraction tool, understanding how to construct a reliable parser is essential. This guide will walk you through the entire process, from understanding the anatomy of a resume to deploying a production-ready parser with robust error handling and high accuracy.<\/p>\n<p>The demand for automated resume parsing has surged over the past decade, as companies receive hundreds or thousands of applications per role. Manual processing is not only time-consuming but also prone to bias and human error. A well-built parser can normalize data, standardize fields, and feed into downstream machine learning models for candidate ranking. However, building one from scratch requires careful consideration of file formats, text extraction strategies, named entity recognition (NER), regex patterns, and post-processing pipelines. In this tutorial, we will adopt a pragmatic, code-first approach, using Python as the primary language because of its rich ecosystem for natural language processing (NLP) and document parsing. By the end, you will have a working architecture that can be extended to support multiple languages, custom ontologies, and advanced deep learning models.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/via.placeholder.com\/800x600\/4a90d9\/ffffff?text=how%20to%20build%20a%20resume%20parser\" alt=\"Article illustration\" style=\"display:block;margin:20px auto;max-width:100%;height:auto;border-radius:8px;\" \/><\/p>\n<h2>Step 1: Define the Scope and Understand Resume Variability<\/h2>\n<p>Before writing a single line of code, you must thoroughly analyze the variability of resumes. Resumes come in countless layouts, fonts, sections, and writing styles. A single individual might have a chronological resume, a functional resume, or a combination resume. Some resumes are written in tables, others in columns, and many use bullet points, while some use paragraphs. You also need to decide which data fields you want to extract. A minimal set typically includes full name, email address, phone number, location, linkedIn URL, education (degree, institution, graduation date), work experience (job title, company, dates, responsibilities), skills list, and certifications. More advanced parsers may extract languages, projects, publications, and even personality indicators.<\/p>\n<p>It is crucial to sample at least 50-100 representative resumes in your target domain to identify common patterns. For example, a resume for a software engineer will frequently contain keywords like &#8220;Python,&#8221; &#8220;AWS,&#8221; &#8220;Agile,&#8221; while a resume for a nurse might emphasize &#8220;patient care,&#8221; &#8220;CPR,&#8221; and &#8220;clinical rotations.&#8221; This domain knowledge will inform your regex patterns and named entity recognition training data. Additionally, you must account for inconsistencies: some resumes list education before experience, others list experience first; some use &#8220;Education&#8221; as a header, others use &#8220;Academic Background&#8221; or &#8220;Qualifications.&#8221; A robust parser should handle these variations through flexible section detection.<\/p>\n<h2>Step 2: Choose the Right Tech Stack and Libraries<\/h2>\n<p>Your choice of libraries will directly impact parsing accuracy, speed, and maintainability. For Python, the core components are:<\/p>\n<ul>\n<li><strong>Document Parsing:<\/strong> For PDFs, the most popular libraries are PyMuPDF (fitz), pdfplumber, and pdfminer.six. PyMuPDF is fast and can extract text with coordinates, while pdfplumber offers powerful table extraction. For DOCX files, python-docx is the standard. For legacy .doc files, you may need to use subprocess to convert them via LibreOffice or Apache POI.<\/li>\n<li><strong>Text Cleaning and Normalization:<\/strong> Use Python\u2019s string methods, regular expressions (re module), and unidecode for handling accented characters. The NLTK or spaCy libraries provide tokenization and lemmatization utilities.<\/li>\n<li><strong>Named Entity Recognition (NER):<\/strong> For extracting names, dates, organizations, etc., you can leverage spaCy\u2019s pre-trained models (e.g., en_core_web_lg) or fine-tune a model on your own annotated resume data. For custom entities like skills, a rule-based approach using a skill taxonomy combined with sequence matching often works better.<\/li>\n<li><strong>Skill Extraction:<\/strong> You can maintain a comprehensive skills dictionary (e.g., from ONET or custom lists) and use fuzzy matching via thefuzz or rapidfuzz to handle spelling variations (e.g., &#8220;Javascript&#8221; vs &#8220;JavaScript&#8221;).<\/li>\n<li><strong>Output Formatting:<\/strong> Use Python\u2019s json module to serialize extracted data into a structured JSON object, which can then be stored in a database or sent to an API.<\/li>\n<\/ul>\n<p>Below is a comparison table of popular PDF parsing libraries to help you decide based on your needs.<\/p>\n<table border=\"1\" cellpadding=\"5\">\n<tr>\n<th>Library<\/th>\n<th>Extraction Speed<\/th>\n<th>Text Accuracy<\/th>\n<th>Table Support<\/th>\n<th>Coordinates<\/th>\n<th>License<\/th>\n<\/tr>\n<tr>\n<td>PyMuPDF (fitz)<\/td>\n<td>Very Fast<\/td>\n<td>High (with clean PDFs)<\/td>\n<td>Basic<\/td>\n<td>Yes<\/td>\n<td>AGPL \/ Commercial<\/td>\n<\/tr>\n<tr>\n<td>pdfplumber<\/td>\n<td>Moderate<\/td>\n<td>Very High<\/td>\n<td>Excellent<\/td>\n<td>Yes<\/td>\n<td>MIT<\/td>\n<\/tr>\n<tr>\n<td>pdfminer.six<\/td>\n<td>Slow<\/td>\n<td>Very High<\/td>\n<td>No<\/td>\n<td>Yes<\/td>\n<td>MIT \/ Python License<\/td>\n<\/tr>\n<\/table>\n<h2>Step 3: Build the Document Ingestion Pipeline<\/h2>\n<p>The first code component is an ingestion module that accepts a file (or a file path), detects its format, and returns the raw text with some metadata. For PDFs, you need to handle both digitally created PDFs (where text is selectable) and scanned PDFs. Scanned PDFs require Optical Character Recognition (OCR) via Tesseract (pytesseract) or Google Cloud Vision \u2013 a significant step that adds complexity. In this tutorial we assume digital PDFs. Below is a simplified skeleton for a document parser class.<\/p>\n<pre><code># Example: document_parser.py\nimport fitz  # PyMuPDF\nfrom docx import Document\n\nclass DocumentParser:\n    def __init__(self, file_path):\n        self.file_path = file_path\n\n    def extract_text(self):\n        if self.file_path.endswith('.pdf'):\n            return self._parse_pdf()\n        elif self.file_path.endswith('.docx'):\n            return self._parse_docx()\n        else:\n            raise ValueError(\"Unsupported file format\")\n\n    def _parse_pdf(self):\n        doc = fitz.open(self.file_path)\n        text = \"\"\n        for page in doc:\n            text += page.get_text()\n        return text\n\n    def _parse_docx(self):\n        doc = Document(self.file_path)\n        text = \"\\n\".join([para.text for para in doc.paragraphs])\n        return text\n<\/code><\/pre>\n<p>This base ingestion gives you a block of raw text. However, layout information is lost. For more advanced parsing, you may want to preserve bounding boxes and font sizes (especially for headers). PyMuPDF\u2019s `page.get_text(&#8220;dict&#8221;)` returns a dictionary with blocks, lines, and spans, allowing you to reconstruct the visual hierarchy. That level of detail is useful for identifying section headers (which are often bold or larger font).<\/p>\n<h2>Step 4: Implement Section Segmentation Using Heuristics and Machine Learning<\/h2>\n<p>After obtaining raw text, the next critical step is to segment the resume into logical sections. This is where most parsers either shine or fail. A simple approach is to maintain a list of common section headers (e.g., &#8220;EDUCATION&#8221;, &#8220;EXPERIENCE&#8221;, &#8220;SKILLS&#8221;, &#8220;PROJECTS&#8221;, &#8220;CERTIFICATIONS&#8221;) and split the text at these markers. Because headers vary in formatting (ALL CAPS, Title Case, bold, or even misspelled), you should use case-insensitive regex with word boundaries. For example:<\/p>\n<pre><code>import re\n\nSECTION_PATTERNS = [\n    (['EDUCATION', 'ACADEMIC BACKGROUND', 'QUALIFICATIONS'], 'education'),\n    (['EXPERIENCE', 'EMPLOYMENT', 'WORK HISTORY', 'PROFESSIONAL EXPERIENCE'], 'experience'),\n    (['SKILLS', 'TECHNICAL SKILLS', 'CORE COMPETENCIES', 'EXPERTISE'], 'skills'),\n    (['PROJECTS', 'KEY PROJECTS', 'PERSONAL PROJECTS'], 'projects'),\n    (['CERTIFICATIONS', 'CERTIFICATES', 'LICENSES'], 'certifications'),\n]\n\ndef segment_resume(text):\n    # Normalize whitespace and convert to uppercase for pattern matching\n    lines = text.split('\\n')\n    sections = {}\n    current_section = 'unknown'\n    current_content = []\n    for line in lines:\n        stripped = line.strip().upper()\n        matched = False\n        for patterns, section_name in SECTION_PATTERNS:\n            for pattern in patterns:\n                if stripped.startswith(pattern):\n                    if current_content:\n                        sections[current_section] = '\\n'.join(current_content)\n                    current_section = section_name\n                    current_content = []\n                    matched = True\n                    break\n            if matched:\n                break\n        if not matched:\n            current_content.append(line)\n    if current_content:\n        sections[current_section] = '\\n'.join(current_content)\n    return sections\n<\/code><\/pre>\n<p>This basic segmentation works for about 60-70% of resumes. To improve, you can incorporate machine learning: train a sequence labeler (e.g., a BiLSTM-CRF or a transformer-based model) to predict whether each line is a section header, and then group lines accordingly. However, that requires annotated data. A pragmatic middle ground is to combine heuristics with a trained classifier for ambiguous headers. Alternatively, you could use a pre-trained BERT model fine-tuned on resume data, as done in several open-source projects like \u201cResumeParser\u201d on GitHub. For the scope of this tutorial, we will stick with the rule-based approach but note where ML can help.<\/p>\n<h2>Step 5: Extract Contact Information and Personal Details<\/h2>\n<p>One of the most standardized parts of any resume is the contact information block, typically at the top. You can use regular expressions to extract:<\/p>\n<ul>\n<li><strong>Email address:<\/strong> Pattern like <code>r'\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b'<\/code><\/li>\n<li><strong>Phone number:<\/strong> Patterns for US numbers (e.g., (123) 456-7890, 123-456-7890, +1 123 456 7890) \u2013 use a regex that handles different formats.<\/li>\n<li><strong>Name:<\/strong> This is trickier. A common method is to assume the name is the first line (or first significant line) of the resume that is not a contact detail. You can also use a pre-trained NER model from spaCy to find PERSON entities; the most frequent one in the first few lines is likely the candidate\u2019s name.<\/li>\n<li><strong>Location:<\/strong> City, state, zip code patterns (e.g., \u201cSan Francisco, CA 94105\u201d).<\/li>\n<li><strong>LinkedIn\/GitHub URLs:<\/strong> Patterns like <code>r'(https?:\/\/(www\\.)?linkedin\\.com\/in\/[A-Za-z0-9_-]+)'<\/code>.<\/li>\n<\/ul>\n<p>Because contact info often appears in a condensed block at the top, you can first extract the top portion (e.g., the first 200 characters) and run extraction on that region to avoid false positives later in the document. After extraction, remove these lines from the text to prevent them from interfering with section segmentation.<\/p>\n<h2>Step 6: Parse Education and Work Experience with Structured Output<\/h2>\n<p>Education and experience sections have their own internal structure. For education, you need to identify degree, major, institution name, and dates. Common patterns include lines like \u201cB.S. in Computer Science, University of California, Berkeley, 2015-2019\u201d or \u201cMaster of Business Administration (MBA) \u2013 2021\u201d. You can use named entity recognition to find organizations (institution) and dates, then apply rule-based logic to infer the degree level (Bachelor, Master, PhD). Some degrees are abbreviated (B.E., M.Sc.) \u2013 maintain a mapping dictionary.<\/p>\n<p>For work experience, each job entry typically contains a job title, company name, employment dates, and a bullet list of responsibilities. The challenge is to segment multiple job entries within the same section. You can look for patterns like a line containing a job title followed by a line containing a company name and date range. Use a greedy split: sort lines by their position in the document and then group by proximity. A more robust method is to treat the experience section as a series of blocks separated by whitespace breaks. You can also use a pre-trained NER model to detect organization names as companies and dates as employment periods.<\/p>\n<p>Here is an example of a simple regex to extract date ranges: <code>r'\\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*\\.?\\s*\\d{4}\\s*[-\u2013to]+\\s*(Jan|Feb|...|Present)?\\s*\\d{4}?\\b'<\/code>. For each job entry, you can then extract the text after the header lines as responsibilities. These can be split by bullet points (often represented by \u201c\u2013\u201d, \u201c*\u201d, or \u201c\u2022\u201d in plain text).<\/p>\n<h2>Step 7: Extract Skills Using a Taxonomy and Fuzzy Matching<\/h2>\n<p>Skill extraction is arguably the most valuable part of a resume parser for matching candidates to job requirements. The approach is to compile a comprehensive list of skills (technical, soft, language) from sources like ONET, Lightcast (formerly Burning Glass), or custom business domains. Then, for each token or n-gram in the skills section (or the entire resume), check if it matches any skill in the taxonomy. Because resumes may contain variations (\u201cNode.js\u201d vs \u201cNodeJS\u201d, \u201cPython\u201d vs \u201cpython\u201d, \u201cwritten communication\u201d vs \u201cWritten Comm\u201d), you should use fuzzy matching with a threshold (e.g., Levenshtein distance < 80%). The thefuzz library is ideal. However, fuzzy matching on the entire resume would be slow \u2013 you can limit to the skills section and also scan for known skill indicators like \u201cProficient in X\u201d or \u201cX (advanced)\u201d.<\/p>\n<p>Additionally, you can use spaCy\u2019s NER to identify product names (e.g., \u201cAWS\u201d, \u201cSalesforce\u201d) and map them to skill categories. Combining rule-based and ML approaches yields the best accuracy. Be careful with false positives: common words like \u201cC\u201d (programming language) vs the letter \u201cC\u201d, or \u201cR\u201d (language) vs the letter. Context matters. For each extracted skill, assign a category (e.g., \u201cProgramming Language\u201d, \u201cCloud\u201d, \u201cDatabase\u201d) and a proficiency level if mentioned (e.g., \u201cadvanced\u201d, \u201cexpert\u201d).<\/p>\n<h2>Step 8: Post-Process and Validate the Extracted Data<\/h2>\n<p>After extraction, you have a JSON-like dictionary with fields like name, email, phone, education list, experience list, skills list, etc. The final step is to run validation checks: is the email format correct? Is the phone number plausible (e.g., length)? Are dates logically ordered (graduation after start)? You should also handle missing or ambiguous fields gracefully. For example, if no name is found, you could fall back to the first line of the resume. If no skills are found, you could try to extract them from the whole text using the taxonomy. You can also implement confidence scores for each extracted field based on the number of evidence sources (NER + regex + position).<\/p>\n<p>Another important post-processing task is deduplication: a skill might appear in both the skills section and the experience section. Merge duplicates and keep the highest proficiency level. Also, for companies and institutions, you may want to normalize names (e.g., \u201cUC Berkeley\u201d \u2192 \u201cUniversity of California, Berkeley\u201d) using a mapping or API like Wikipedia. This normalization is especially valuable for downstream analytics.<\/p>\n<h2>Tips and Best Practices for Building a Resume Parser<\/h2>\n<h3>Tip 1: Always Test on a Diverse Set of Resumes<\/h3>\n<p>Your parser\u2019s accuracy will vary dramatically depending on the quality and layout of source documents. Build a test set of at least 200 resumes from different industries, job levels, and formats (single column, two columns, tables, infographics). For each resume, manually annotate the ground truth fields. Use this test set to calculate precision, recall, and F1-score for each field. Fine-tune your regex and ML models based on failure cases. Also consider edge cases like resumes written in all caps, resumes in languages other than English, and resumes with typos.<\/p>\n<h3>Tip 2: Use Layout Information to Improve Segmentation<\/h3>\n<p>When you extract text from PDFs using PyMuPDF or pdfplumber, you can also retrieve bounding boxes and font sizes. Use these to identify headings: text that is bold, larger, or has different styling is likely a section header. You can also recognize multi-column layouts by analyzing the x-coordinates of text lines. This extra information significantly boosts segmentation accuracy for resumes that use creative design elements.<\/p>\n<h3>Tip 3: Implement a Modular Pipeline for Easy Maintenance<\/h3>\n<p>Resume parsing is not a one-shot development task; categories, skill taxonomies, and company names change over time. Structure your code as a pipeline of independent components: document reader \u2192 preprocessor \u2192 section segmenter \u2192 field extractors (contact, education, experience, skills) \u2192 validator \u2192 output formatter. Each component should be configurable via a YAML or JSON configuration file. This modularity allows you to swap out a regex-based extractor with a machine learning model without rewriting the entire system.<\/p>\n<h3>Tip 4: Handle Scanned PDFs Separately<\/h3>\n<p>If your use case involves many scanned resumes (e.g., from older paper applications), you need an OCR pipeline. However, OCR is imperfect and introduces new errors like misrecognized letters, broken words, and incorrect line spacing. Use an advanced OCR engine like Azure Form Recognizer or Google Cloud Vision, which can also extract tables and form fields. Alternatively, you can pre-process scanned PDFs with Tesseract after converting pages to images. Always evaluate the OCR output before feeding into the parser.<\/p>\n<h2>Frequently Asked Questions<\/h2>\n<h3>Q1: What is the best programming language for building a resume parser?<\/h3>\n<p>Python is by far the most popular choice due to its extensive NLP and document parsing libraries. However, if you need very high performance (e.g., parsing millions of resumes per day), you might consider using Java (with Apache Tika for document parsing) or Go. For most teams, Python\u2019s productivity outweighs the speed difference.<\/p>\n<h3>Q2: Can I use pre-trained APIs instead of building my own parser?<\/h3>\n<p>Yes, services like Sovren, Rosetta, or Rchilli offer resume parsing APIs. These can be integrated quickly but come with cost and data privacy concerns. For in-house development, a custom parser gives you full control over accuracy and data security, at the expense of development time.<\/p>\n<h3>Q3: How do I handle resumes that are one-page PDFs vs multi-page?<\/h3>\n<p>Multi-page resumes are handled by concatenating text from all pages. However, be aware that headers and footers (like page numbers) can interfere with section detection. Strip page numbers using a pattern like \u201cPage X of Y\u201d before segmentation. Also, some resumes have a second page with additional projects or publications \u2013 ensure your segmentation can handle multiple instances of the same section (e.g., two education entries on different pages).<\/p>\n<h3>Q4: What are the common reasons for low accuracy?<\/h3>\n<p>Low accuracy often stems from poor document ingestion (especially OCR errors), incomplete section header patterns, and over-reliance on a single extraction method. Another frequent issue is not normalizing the text (removing non-breaking spaces, special characters, etc.). Also, many parsers fail to handle resumes with a functional layout (skills listed before experience) or resumes that use tables for organization. Continuously analyze failure modes and iterate.<\/p>\n<h3>Q5: How can I improve the extraction of dates?<\/h3>\n<p>Dates appear in numerous formats: \u201cJan 2018 \u2013 Present\u201d, \u201c01\/2018-12\/2020\u201d, \u201c2018-2020\u201d, etc. Build a comprehensive regex that covers month names (abbreviated and full), 2-digit vs 4-digit years, and separators like hyphen, slash, and em dash. Consider using the dateparser library to parse natural language dates like \u201cMarch 2020\u201d into a standard YYYY-MM format. Additionally, associate dates with their context (education vs work) to avoid mixing them.<\/p>\n<h3>Q6: Do I need to update the skill taxonomy regularly?<\/h3>\n<p>Absolutely. The technology landscape changes rapidly \u2013 new programming languages, frameworks, and tools emerge every year. A static skill list will quickly become outdated. Set up a periodic update process: scrape job postings for new skills, use APIs like Stack Overflow Tags or LinkedIn Skills, or allow users to tag new skills that can be reviewed and added.<\/p>\n<h2>Conclusion<\/h2>\n<p>Building a robust resume parser is an iterative process that blends rule-based logic, machine learning, and continuous refinement. In this guide, we have walked through the key steps: understanding resume variability, selecting the right libraries, ingesting documents, segmenting sections, extracting contact info, education, experience, and skills, and finally post-processing the output. We also covered best practices like testing on diverse resumes, using layout features, maintaining modular code, and handling OCR separately.<\/p>\n<p>Remember that no parser will ever be 100% accurate on all resumes, but with careful design, you can achieve over 90% precision on the most critical fields (email, phone, name) and 80% or higher on education and experience. As your parser processes more resumes, you can collect feedback and retrain models to improve. The field of automated resume parsing is still evolving, with deep learning approaches (like BERT-based models and graph neural networks) showing promise for end-to-end processing. By following the architecture outlined here, you will have a strong foundation that can be extended and scaled to meet the needs of your organization or product.<\/p>\n<p>Finally, always be aware of ethical considerations: resume parsers can inadvertently introduce bias if the training data is not diverse. Use fairness-aware evaluation, and consider allowing candidates to review and correct the extracted data before it is used in hiring decisions. With thoughtful implementation, a resume parser can become a powerful tool that saves time and provides a more objective view of each applicant\u2019s qualifications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to Build a Resume Parser: A Comprehensive Step-by-Step Guide for Developers Building a resume parser is one of the most common yet challenging tasks in the realm of human resources technology and natural language processing. A resume parser extracts structured data\u2014such as contact details, education, work experience, skills, and certifications\u2014from unstructured or semi-structured resume &hellip; <\/p>\n","protected":false},"author":2716,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[],"tags":[],"class_list":["post-1025","post","type-post","status-publish","format-standard","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/posts\/1025","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/users\/2716"}],"replies":[{"embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/comments?post=1025"}],"version-history":[{"count":0,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/posts\/1025\/revisions"}],"wp:attachment":[{"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/media?parent=1025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/categories?post=1025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sumberlaba.com\/index.php\/wp-json\/wp\/v2\/tags?post=1025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}