 {"id":521255,"date":"2026-06-26T08:47:35","date_gmt":"2026-06-26T15:47:35","guid":{"rendered":"https:\/\/jorgep.com\/blog\/?page_id=521255"},"modified":"2026-08-05T21:19:28","modified_gmt":"2026-08-06T04:19:28","slug":"latest-token-prices","status":"publish","type":"page","link":"https:\/\/jorgep.com\/blog\/latest-token-prices\/","title":{"rendered":"Latest Token Prices"},"content":{"rendered":"<style>.kb-row-layout-id521303_9f8b01-eb > .kt-row-column-wrap{align-content:start;}:where(.kb-row-layout-id521303_9f8b01-eb > .kt-row-column-wrap) > .wp-block-kadence-column{justify-content:start;}.kb-row-layout-id521303_9f8b01-eb > .kt-row-column-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:var(--global-kb-gap-md, 2rem);padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);grid-template-columns:minmax(0, calc(60% - ((var(--global-kb-gap-md, 2rem) * 1 )\/2)))minmax(0, calc(40% - ((var(--global-kb-gap-md, 2rem) * 1 )\/2)));}.kb-row-layout-id521303_9f8b01-eb > .kt-row-layout-overlay{opacity:0.30;}@media all and (max-width: 1024px){.kb-row-layout-id521303_9f8b01-eb > .kt-row-column-wrap{grid-template-columns:minmax(0, 2fr) minmax(0, 1fr);}}@media all and (max-width: 767px){.kb-row-layout-id521303_9f8b01-eb > .kt-row-column-wrap{grid-template-columns:minmax(0, 1fr);}}<\/style><div class=\"kb-row-layout-wrap kb-row-layout-id521303_9f8b01-eb alignnone wp-block-kadence-rowlayout\"><div class=\"kt-row-column-wrap kt-has-2-columns kt-row-layout-left-golden kt-tab-layout-inherit kt-mobile-layout-row kt-row-valign-top\">\n<style>.kadence-column521303_495eef-f2 > .kt-inside-inner-col{display:flex;}.kadence-column521303_495eef-f2 > .kt-inside-inner-col,.kadence-column521303_495eef-f2 > .kt-inside-inner-col:before{border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-right-radius:0px;border-bottom-left-radius:0px;}.kadence-column521303_495eef-f2 > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column521303_495eef-f2 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}.kadence-column521303_495eef-f2 > .kt-inside-inner-col > .aligncenter{width:100%;}.kt-row-column-wrap > .kadence-column521303_495eef-f2{align-self:center;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_495eef-f2{align-self:auto;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_495eef-f2 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}.kadence-column521303_495eef-f2 > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column521303_495eef-f2{position:relative;}@media all and (max-width: 1024px){.kt-row-column-wrap > .kadence-column521303_495eef-f2{align-self:center;}}@media all and (max-width: 1024px){.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_495eef-f2{align-self:auto;}}@media all and (max-width: 1024px){.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_495eef-f2 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 1024px){.kadence-column521303_495eef-f2 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}@media all and (max-width: 767px){.kt-row-column-wrap > .kadence-column521303_495eef-f2{align-self:center;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_495eef-f2{align-self:auto;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_495eef-f2 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}.kadence-column521303_495eef-f2 > .kt-inside-inner-col{flex-direction:column;justify-content:center;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column521303_495eef-f2\"><div class=\"kt-inside-inner-col\"><style>.wp-block-kadence-advancedheading.kt-adv-heading521303_7d0a79-b0, .wp-block-kadence-advancedheading.kt-adv-heading521303_7d0a79-b0[data-kb-block=\"kb-adv-heading521303_7d0a79-b0\"]{padding-top:var(--global-kb-spacing-xs, 1rem);padding-right:var(--global-kb-spacing-xs, 1rem);padding-bottom:var(--global-kb-spacing-xs, 1rem);padding-left:var(--global-kb-spacing-xs, 1rem);text-align:left;font-size:var(--global-kb-font-size-sm, 0.9rem);font-style:normal;}.wp-block-kadence-advancedheading.kt-adv-heading521303_7d0a79-b0 mark.kt-highlight, .wp-block-kadence-advancedheading.kt-adv-heading521303_7d0a79-b0[data-kb-block=\"kb-adv-heading521303_7d0a79-b0\"] mark.kt-highlight{font-style:normal;color:#f76a0c;-webkit-box-decoration-break:clone;box-decoration-break:clone;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.wp-block-kadence-advancedheading.kt-adv-heading521303_7d0a79-b0 img.kb-inline-image, .wp-block-kadence-advancedheading.kt-adv-heading521303_7d0a79-b0[data-kb-block=\"kb-adv-heading521303_7d0a79-b0\"] img.kb-inline-image{width:150px;vertical-align:baseline;}<\/style>\n<p class=\"kt-adv-heading521303_7d0a79-b0 wp-block-kadence-advancedheading has-theme-palette-7-background-color has-background\" data-kb-block=\"kb-adv-heading521303_7d0a79-b0\">ChatGPT, Claude, Gemini&#8230; where was that conversation \/ image again?  Stop digging through tabs. <strong>Unified AI Chat Hub<\/strong> brings all your favorite models, chats, and AI-generated images into one searchable home. Compare responses, organize projects, and secure your ideas in one place.  <br>Your ideas \/chats and images deserve one discoverable home:     <br><strong>Learn more:<\/strong> <a href=\"https:\/\/35sites.com\/unifiedchathub\">https:\/\/35sites.com\/unifiedchathub<\/a><\/p>\n<\/div><\/div>\n\n\n<style>.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{display:flex;}.kadence-column521303_d12ef6-8b > .kt-inside-inner-col,.kadence-column521303_d12ef6-8b > .kt-inside-inner-col:before{border-top-left-radius:0px;border-top-right-radius:0px;border-bottom-right-radius:0px;border-bottom-left-radius:0px;}.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{column-gap:var(--global-kb-gap-sm, 1rem);}.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{flex-direction:column;justify-content:flex-start;}.kadence-column521303_d12ef6-8b > .kt-inside-inner-col > .aligncenter{width:100%;}.kt-row-column-wrap > .kadence-column521303_d12ef6-8b{align-self:flex-start;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_d12ef6-8b{align-self:auto;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{flex-direction:column;justify-content:flex-start;}.kadence-column521303_d12ef6-8b > .kt-inside-inner-col:before{opacity:0.3;}.kadence-column521303_d12ef6-8b{position:relative;}@media all and (max-width: 1024px){.kt-row-column-wrap > .kadence-column521303_d12ef6-8b{align-self:flex-start;}}@media all and (max-width: 1024px){.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_d12ef6-8b{align-self:auto;}}@media all and (max-width: 1024px){.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{flex-direction:column;justify-content:flex-start;}}@media all and (max-width: 1024px){.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{flex-direction:column;justify-content:flex-start;}}@media all and (max-width: 767px){.kt-row-column-wrap > .kadence-column521303_d12ef6-8b{align-self:flex-start;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_d12ef6-8b{align-self:auto;}.kt-inner-column-height-full:not(.kt-has-1-columns) > .wp-block-kadence-column.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{flex-direction:column;justify-content:flex-start;}.kadence-column521303_d12ef6-8b > .kt-inside-inner-col{flex-direction:column;justify-content:flex-start;}}<\/style>\n<div class=\"wp-block-kadence-column kadence-column521303_d12ef6-8b\"><div class=\"kt-inside-inner-col\"><div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/35sites.com\/unifiedchathub\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"409\" src=\"https:\/\/jorgep.com\/blog\/wp-content\/uploads\/UnifiedChatHub-Banner-20260626125045-1024x409.png\" alt=\"\" class=\"wp-image-521289\" srcset=\"https:\/\/jorgep.com\/blog\/wp-content\/uploads\/UnifiedChatHub-Banner-20260626125045-1024x409.png 1024w, https:\/\/jorgep.com\/blog\/wp-content\/uploads\/UnifiedChatHub-Banner-20260626125045-300x120.png 300w, https:\/\/jorgep.com\/blog\/wp-content\/uploads\/UnifiedChatHub-Banner-20260626125045-768x307.png 768w, https:\/\/jorgep.com\/blog\/wp-content\/uploads\/UnifiedChatHub-Banner-20260626125045-1536x614.png 1536w, https:\/\/jorgep.com\/blog\/wp-content\/uploads\/UnifiedChatHub-Banner-20260626125045.png 1983w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div><\/div><\/div>\n\n<\/div><\/div>\n\n\n<h3 class=\"wp-block-heading\">Understanding AI Model Pricing Through OpenRouter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">One of the biggest advantages of using OpenRouter.ai is that it provides a single API for accessing hundreds of AI models from leading providers including OpenAI, Anthropic, Google, xAI, Qwen, DeepSeek, Mistral, and many others. Rather than maintaining separate accounts and integrations for each AI vendor, developers can compare models, switch between them with minimal code changes, and choose the best model for each specific task. OpenRouter generally passes through the model provider&#8217;s published token pricing while providing a unified billing and management experience. <a href=\"https:\/\/openrouter.ai\/pricing?utm_source=jorgep.com\" target=\"_blank\" rel=\"noreferrer noopener\">OpenRouter Pricing<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The pricing information below is intended to provide a convenient comparison of many of today&#8217;s most popular frontier language models. Costs are typically shown per one million input and output tokens, making it easier to estimate application expenses across different providers. Since AI models vary significantly in capability, speed, reasoning ability, and cost, selecting the lowest-priced model is not always the most economical choice. In many cases, a faster or more capable model can complete a task using fewer prompts or less developer effort, resulting in a lower overall cost.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more information on Tokens please see my <a href=\"https:\/\/jorgep.com\/blog\/tag\/tokens\/\" data-type=\"post\" data-id=\"518307\" target=\"_blank\" rel=\"noreferrer noopener\">tokens <\/a>or my <a href=\"https:\/\/jorgep.com\/blog\/tag\/local-ai\/\" data-type=\"post_tag\" data-id=\"986\">Local AI<\/a> blog post<\/p>\n\n\n\n<blockquote class=\"wp-block-quote has-small-font-size is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Disclaimer<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AI model pricing changes frequently as providers introduce new models, adjust pricing, or offer promotional rates. Always verify current pricing before making purchasing or architectural decisions. The official OpenRouter model catalog remains the authoritative source for current pricing and availability. <a href=\"https:\/\/openrouter.ai\/pricing?utm_source=jorgep.com\" target=\"_blank\" rel=\"noreferrer noopener\">OpenRouter Model Catalog &amp; Pricing<\/a><\/li>\n\n\n\n<li>Most production AI applications <strong>do not rely on a single model<\/strong>. Instead, they route different requests to the model best suited for each task. For example, an application might use an inexpensive, high-speed model for summarization, a premium reasoning model for complex analysis, and a specialized coding model for software development. This multi-model approach often delivers the best balance of cost, performance, and quality.<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">This is a list of the latest Token prices based on the provider:<\/p>\n\n\n\n<div id=\"openrouter-app-wrapper\">\n    <style>\n        #openrouter-app-wrapper {\n            --bg: #f8fafc;\n            --card-bg: #ffffff;\n            --border: #cbd5e1;\n            --text: #0f172a;\n            --text-muted: #64748b;\n            --accent: #2563eb;\n            --accent-hover: #1d4ed8;\n            --success: #16a34a;\n            --warning: #ca8a04;\n            --danger: #dc2626;\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n            background-color: var(--bg);\n            color: var(--text);\n            padding: 24px;\n            border-radius: 12px;\n            line-height: 1.5;\n            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);\n        }\n\n        #openrouter-app-wrapper .container { max-width: 1200px; margin: 0 auto; }\n\n        #openrouter-app-wrapper header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            flex-wrap: wrap;\n            gap: 16px;\n            margin-bottom: 24px;\n            padding-bottom: 16px;\n            border-bottom: 1px solid var(--border);\n        }\n\n        #openrouter-app-wrapper h1 { font-size: 1.5rem; font-weight: 700; margin: 0; color: var(--text); }\n\n        #openrouter-app-wrapper .controls-bar {\n            display: flex;\n            gap: 12px;\n            flex-wrap: wrap;\n            align-items: center;\n            margin-bottom: 20px;\n        }\n\n        #openrouter-app-wrapper input[type=\"text\"], \n        #openrouter-app-wrapper input[type=\"number\"], \n        #openrouter-app-wrapper select {\n            background-color: var(--card-bg);\n            border: 1px solid var(--border);\n            color: var(--text);\n            padding: 8px 12px;\n            border-radius: 6px;\n            font-size: 0.9rem;\n            outline: none;\n        }\n\n        #openrouter-app-wrapper input[type=\"text\"]:focus, \n        #openrouter-app-wrapper input[type=\"number\"]:focus, \n        #openrouter-app-wrapper select:focus {\n            border-color: var(--accent);\n            box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);\n        }\n\n        #openrouter-app-wrapper .search-input { flex-grow: 1; min-width: 200px; }\n\n        #openrouter-app-wrapper button {\n            background-color: var(--accent);\n            color: white;\n            border: none;\n            padding: 8px 16px;\n            border-radius: 6px;\n            font-weight: 500;\n            cursor: pointer;\n            display: inline-flex;\n            align-items: center;\n            gap: 6px;\n            font-size: 0.9rem;\n            transition: background-color 0.2s;\n        }\n\n        #openrouter-app-wrapper button:hover { background-color: var(--accent-hover); }\n\n        #openrouter-app-wrapper .status-banner {\n            padding: 10px 14px;\n            border-radius: 6px;\n            margin-bottom: 20px;\n            font-size: 0.875rem;\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n        }\n        #openrouter-app-wrapper .status-info { background: #eff6ff; color: #1e40af; border-left: 4px solid var(--accent); }\n        #openrouter-app-wrapper .status-success { background: #f0fdf4; color: #166534; border-left: 4px solid var(--success); }\n        #openrouter-app-wrapper .status-warning { background: #fefce8; color: #854d0e; border-left: 4px solid var(--warning); }\n        #openrouter-app-wrapper .status-error { background: #fef2f2; color: #991b1b; border-left: 4px solid var(--danger); }\n\n        #openrouter-app-wrapper .table-wrapper {\n            background-color: var(--card-bg);\n            border: 1px solid var(--border);\n            border-radius: 8px;\n            overflow-x: auto;\n            box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.05);\n        }\n\n        #openrouter-app-wrapper table {\n            width: 100%;\n            border-collapse: collapse;\n            text-align: left;\n            font-size: 0.875rem;\n        }\n\n        #openrouter-app-wrapper th, \n        #openrouter-app-wrapper td {\n            padding: 12px 16px;\n            border-bottom: 1px solid var(--border);\n        }\n\n        #openrouter-app-wrapper th {\n            background-color: #f1f5f9;\n            font-weight: 600;\n            color: var(--text);\n            cursor: pointer;\n            user-select: none;\n        }\n\n        #openrouter-app-wrapper th:hover { background-color: #e2e8f0; }\n        #openrouter-app-wrapper tr:last-child td { border-bottom: none; }\n        #openrouter-app-wrapper tr:hover td { background-color: #f8fafc; }\n\n        #openrouter-app-wrapper .free-badge {\n            background-color: #dcfce7;\n            color: #166534;\n            font-size: 0.7rem;\n            font-weight: 700;\n            padding: 2px 6px;\n            border-radius: 4px;\n            margin-left: 6px;\n            text-transform: uppercase;\n        }\n\n        #openrouter-app-wrapper .copy-btn {\n            background: transparent;\n            color: var(--text-muted);\n            padding: 4px;\n            border-radius: 4px;\n        }\n        #openrouter-app-wrapper .copy-btn:hover { color: var(--text); background: rgba(0, 0, 0, 0.05); }\n        #openrouter-app-wrapper .copy-btn svg { width: 14px; height: 14px; }\n\n        \/* Modal Styles *\/\n        #openrouter-app-wrapper .modal-overlay {\n            position: fixed;\n            top: 0; left: 0; right: 0; bottom: 0;\n            background: rgba(15, 23, 42, 0.5);\n            display: none;\n            align-items: center;\n            justify-content: center;\n            z-index: 99999;\n            padding: 20px;\n        }\n\n        #openrouter-app-wrapper .modal-card {\n            background: var(--card-bg);\n            border: 1px solid var(--border);\n            border-radius: 12px;\n            width: 100%;\n            max-width: 850px;\n            max-height: 90vh;\n            display: flex;\n            flex-direction: column;\n            overflow: hidden;\n            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n        }\n\n        #openrouter-app-wrapper .modal-header {\n            padding: 16px 24px;\n            border-bottom: 1px solid var(--border);\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n\n        #openrouter-app-wrapper .modal-body {\n            padding: 24px;\n            overflow-y: auto;\n        }\n\n        #openrouter-app-wrapper .modal-close {\n            background: transparent;\n            color: var(--text-muted);\n            font-size: 1.5rem;\n            padding: 0;\n            line-height: 1;\n        }\n\n        #openrouter-app-wrapper .calc-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n            gap: 16px;\n            margin-bottom: 20px;\n            background: #f1f5f9;\n            padding: 16px;\n            border-radius: 8px;\n        }\n\n        #openrouter-app-wrapper .calc-field {\n            display: flex;\n            flex-direction: column;\n            gap: 6px;\n        }\n\n        #openrouter-app-wrapper .calc-field label {\n            font-size: 0.8rem;\n            color: var(--text-muted);\n            font-weight: 600;\n            text-transform: uppercase;\n        }\n    <\/style>\n\n    <div class=\"container\">\n        <header>\n            <div>\n                <h1>OpenRouter Pricing Explorer<\/h1>\n                <p style=\"color: var(--text-muted); font-size: 0.875rem; margin: 0;\">Server Cached Data (12h Sync)<\/p>\n            <\/div>\n            <div style=\"display: flex; gap: 10px;\">\n                <button id=\"openCalcBtn\">\n                    <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\"\/><line x1=\"8\" y1=\"6\" x2=\"16\" y2=\"6\"\/><line x1=\"16\" y1=\"14\" x2=\"16\" y2=\"18\"\/><path d=\"M16 10h.01\"\/><path d=\"M12 10h.01\"\/><path d=\"M8 10h.01\"\/><path d=\"M12 14h.01\"\/><path d=\"M8 14h.01\"\/><path d=\"M12 18h.01\"\/><path d=\"M8 18h.01\"\/><\/svg>\n                    Token Cost Calculator\n                <\/button>\n                <button id=\"reloadBtn\" style=\"background-color: var(--card-bg); color: var(--text); border: 1px solid var(--border);\">Reload Data<\/button>\n            <\/div>\n        <\/header>\n\n        <div id=\"statusBanner\" class=\"status-banner status-info\">\n            <span id=\"statusText\">Initializing model data reader&#8230;<\/span>\n        <\/div>\n\n        <div class=\"controls-bar\">\n            <input type=\"text\" id=\"searchInput\" class=\"search-input\" placeholder=\"Search by model name or provider (e.g. gemini, anthropic, llama)...\">\n            <select id=\"mainCategoryFilter\">\n                <option value=\"all\">All Categories<\/option>\n                <option value=\"common\">Commonly Used<\/option>\n                <option value=\"opensource\">Open Source<\/option>\n                <option value=\"frontier\">Frontier<\/option>\n                <option value=\"free\">Free Tier (:free)<\/option>\n            <\/select>\n            <span id=\"modelCount\" style=\"color: var(--text-muted); font-size: 0.85rem; margin-left: auto;\">0 models<\/span>\n        <\/div>\n\n        <div class=\"table-wrapper\">\n            <table>\n                <thead>\n                    <tr>\n                        <th id=\"th-id\">Model ID \/ Name \u21d5<\/th>\n                        <th id=\"th-input\">Prompt ($\/1M Tokens) \u21d5<\/th>\n                        <th id=\"th-output\">Completion ($\/1M Tokens) \u21d5<\/th>\n                        <th id=\"th-context\">Context Window \u21d5<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody id=\"mainTableRows\">\n                    <tr><td colspan=\"4\" style=\"text-align:center; padding: 40px;\">Loading models&#8230;<\/td><\/tr>\n                <\/tbody>\n            <\/table>\n        <\/div>\n    <\/div>\n\n    <!-- Calculator Modal -->\n    <div id=\"calcModal\" class=\"modal-overlay\">\n        <div class=\"modal-card\">\n            <div class=\"modal-header\">\n                <h2 style=\"font-size: 1.1rem; margin:0; color: var(--text);\">Token Cost Calculator<\/h2>\n                <button class=\"modal-close\" id=\"closeCalcBtn\">&times;<\/button>\n            <\/div>\n            <div class=\"modal-body\">\n                <div class=\"calc-grid\">\n                    <div class=\"calc-field\">\n                        <label for=\"inTok\">Input Tokens<\/label>\n                        <input type=\"number\" id=\"inTok\" value=\"100000\" step=\"1000\">\n                    <\/div>\n                    <div class=\"calc-field\">\n                        <label for=\"outTok\">Output Tokens<\/label>\n                        <input type=\"number\" id=\"outTok\" value=\"20000\" step=\"1000\">\n                    <\/div>\n                    <div class=\"calc-field\">\n                        <label for=\"categoryFilter\">Preset Filter<\/label>\n                        <select id=\"categoryFilter\">\n                            <option value=\"common\">Commonly Used<\/option>\n                            <option value=\"opensource\">Open Source<\/option>\n                            <option value=\"frontier\">Frontier Models<\/option>\n                            <option value=\"all\">All Models<\/option>\n                        <\/select>\n                    <\/div>\n                <\/div>\n\n                <h3 style=\"font-size: 0.95rem; margin-bottom: 12px; color: var(--text-muted);\">Calculated Estimates<\/h3>\n\n                <div class=\"table-wrapper\" style=\"max-height: 400px; overflow-y: auto;\">\n                    <table>\n                        <thead>\n                            <tr>\n                                <th>Model<\/th>\n                                <th>Input Cost<\/th>\n                                <th>Output Cost<\/th>\n                                <th>Total Cost<\/th>\n                            <\/tr>\n                        <\/thead>\n                        <tbody id=\"calcRows\"><\/tbody>\n                    <\/table>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <script>\n    (function() {\n        const LIVE_API_URL = \"https:\/\/openrouter.ai\/api\/v1\/models\";\n\n        const PRESET_CATEGORIES = {\n            common: [\"google\/gemini-2.5-flash\", \"google\/gemini-2.0-flash-001\", \"openai\/gpt-4o-mini\", \"anthropic\/claude-3.5-haiku\", \"deepseek\/deepseek-chat\"],\n            opensource: [\"meta-llama\/llama-3.3-70b-instruct\", \"mistralai\/mistral-large-2411\", \"qwen\/qwen-2.5-72b-instruct\", \"deepseek\/deepseek-r1\"],\n            frontier: [\"openai\/gpt-4o\", \"anthropic\/claude-3.7-sonnet\", \"google\/gemini-2.5-pro\", \"deepseek\/deepseek-r1\"]\n        };\n\n        let rawModelData = [];\n        let currentSortField = 'id';\n        let sortAscending = true;\n\n        function setStatus(message, type = \"info\") {\n            const statusBanner = document.getElementById(\"statusBanner\");\n            const statusText = document.getElementById(\"statusText\");\n            if (statusText && statusBanner) {\n                statusText.innerText = message;\n                statusBanner.className = `status-banner status-${type}`;\n            }\n        }\n\n        async function loadData() {\n            if (window.cachedModelsData && window.cachedModelsData.data && window.cachedModelsData.data.length > 0) {\n                processAndStoreData(window.cachedModelsData, \"Cached (12h TTL)\");\n                return;\n            }\n\n            try {\n                setStatus(\"Server cache empty. Fetching live from OpenRouter API...\", \"info\");\n                const apiRes = await fetch(LIVE_API_URL);\n                if (apiRes.ok) {\n                    const apiJson = await apiRes.json();\n                    processAndStoreData(apiJson, \"Loaded live\");\n                    return;\n                }\n            } catch (err) {\n                console.warn(\"Live API fetch failed:\", err);\n            }\n\n            setStatus(\"Failed to load OpenRouter model data.\", \"error\");\n        }\n\n        function processAndStoreData(rawData, successMsg) {\n            const list = Array.isArray(rawData) ? rawData : (rawData.data || []);\n            \n            rawModelData = list.map(m => {\n                const promptPrice = m.pricing?.prompt ? parseFloat(m.pricing.prompt) * 1000000 : (m.input ? parseFloat(m.input) * 1000000 : 0);\n                const completionPrice = m.pricing?.completion ? parseFloat(m.pricing.completion) * 1000000 : (m.output ? parseFloat(m.output) * 1000000 : 0);\n                \n                return {\n                    id: m.id || '',\n                    name: m.name || m.id || 'Unknown',\n                    input: promptPrice,\n                    output: completionPrice,\n                    context_length: m.context_length || m.context || 0\n                };\n            });\n\n            setStatus(`${successMsg} (${rawModelData.length} models)`, \"success\");\n            renderMainTable();\n            renderCostTable();\n        }\n\n        function categorizeModel(id) {\n            const lower = id.toLowerCase();\n            if (lower.includes(\"llama\") || lower.includes(\"mistral\") || lower.includes(\"qwen\") || lower.includes(\"deepseek\")) return \"opensource\";\n            if (lower.includes(\"gpt-4\") || lower.includes(\"claude-3.7\") || lower.includes(\"gemini-2.5-pro\")) return \"frontier\";\n            return \"common\";\n        }\n\n        function escapeHtml(str) {\n            return String(str).replace(\/[&<>\"']\/g, m => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[m]));\n        }\n\n        window.copyOpenRouterModelId = function(id, btn) {\n            navigator.clipboard.writeText(id).then(() => {\n                const orig = btn.innerHTML;\n                btn.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#16a34a\" stroke-width=\"2\"><polyline points=\"20 6 9 17 4 12\"><\/polyline><\/svg>`;\n                setTimeout(() => { btn.innerHTML = orig; }, 1500);\n            });\n        };\n\n        function renderMainTable() {\n            const search = document.getElementById(\"searchInput\").value.toLowerCase();\n            const category = document.getElementById(\"mainCategoryFilter\").value;\n\n            let filtered = rawModelData.filter(m => {\n                const matchesSearch = m.id.toLowerCase().includes(search) || m.name.toLowerCase().includes(search);\n                if (!matchesSearch) return false;\n\n                if (category === \"free\") return m.id.endsWith(\":free\") || (m.input === 0 && m.output === 0);\n                if (category === \"all\") return true;\n                return categorizeModel(m.id) === category;\n            });\n\n            filtered.sort((a, b) => {\n                let valA = a[currentSortField];\n                let valB = b[currentSortField];\n                if (typeof valA === 'string') {\n                    return sortAscending ? valA.localeCompare(valB) : valB.localeCompare(valA);\n                }\n                return sortAscending ? valA - valB : valB - valA;\n            });\n\n            document.getElementById(\"modelCount\").innerText = `${filtered.length} of ${rawModelData.length} models`;\n\n            const rowsHtml = filtered.length ? filtered.map(m => `\n                <tr>\n                    <td>\n                        <b>${escapeHtml(m.name)}<\/b>\n                        <br><span style=\"color:var(--text-muted); font-size:0.75rem;\">${escapeHtml(m.id)}<\/span>\n                        ${m.id.endsWith(':free') ? '<span class=\"free-badge\">FREE<\/span>' : ''}\n                        <button class=\"copy-btn\" onclick=\"window.copyOpenRouterModelId('${m.id}', this)\" title=\"Copy Model ID\">\n                            <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg>\n                        <\/button>\n                    <\/td>\n                    <td>$${m.input.toFixed(4)}<\/td>\n                    <td>$${m.output.toFixed(4)}<\/td>\n                    <td>${m.context_length ? m.context_length.toLocaleString() : 'N\/A'}<\/td>\n                <\/tr>\n            `).join(\"\") : `<tr><td colspan=\"4\" style=\"text-align:center; padding: 20px; color: var(--text-muted);\">No matching models found<\/td><\/tr>`;\n\n            document.getElementById(\"mainTableRows\").innerHTML = rowsHtml;\n        }\n\n        function sortTable(field) {\n            if (currentSortField === field) {\n                sortAscending = !sortAscending;\n            } else {\n                currentSortField = field;\n                sortAscending = true;\n            }\n            renderMainTable();\n        }\n\n        function renderCostTable() {\n            const inTok = Number(document.getElementById(\"inTok\").value) || 0;\n            const outTok = Number(document.getElementById(\"outTok\").value) || 0;\n            const selectedCategory = document.getElementById(\"categoryFilter\").value;\n\n            let processedDataset = rawModelData;\n\n            if (selectedCategory !== \"all\" && PRESET_CATEGORIES[selectedCategory]) {\n                const presetList = PRESET_CATEGORIES[selectedCategory];\n                const exactMatches = rawModelData.filter(m => presetList.includes(m.id));\n                \n                processedDataset = exactMatches.length > 0 \n                    ? exactMatches \n                    : rawModelData.filter(m => categorizeModel(m.id) === selectedCategory);\n            }\n\n            const pricedModels = processedDataset.map(m => {\n                const inputCost = (inTok \/ 1000000) * m.input;\n                const outputCost = (outTok \/ 1000000) * m.output;\n                const total = inputCost + outputCost;\n                return { id: m.id, name: m.name, inputCost, outputCost, total };\n            });\n\n            pricedModels.sort((a, b) => a.total - b.total);\n\n            document.getElementById(\"calcRows\").innerHTML = pricedModels.length ? pricedModels.map(m => `\n                <tr>\n                    <td>\n                        ${escapeHtml(m.id)} \n                        ${m.id.endsWith(':free') ? '<span class=\"free-badge\">FREE<\/span>' : ''}\n                        <button class=\"copy-btn\" onclick=\"window.copyOpenRouterModelId('${m.id}', this)\" title=\"Copy Model ID\">\n                            <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"><\/rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"><\/path><\/svg>\n                        <\/button>\n                    <\/td>\n                    <td>$${m.inputCost.toFixed(6)}<\/td>\n                    <td>$${m.outputCost.toFixed(6)}<\/td>\n                    <td><b>$${m.total.toFixed(6)}<\/b><\/td>\n                <\/tr>\n            `).join(\"\") : `<tr><td colspan=\"4\" style=\"text-align:center; padding: 12px; color: var(--text-muted);\">No models available<\/td><\/tr>`;\n        }\n\n        function setupEventListeners() {\n            document.getElementById(\"searchInput\").addEventListener(\"input\", renderMainTable);\n            document.getElementById(\"mainCategoryFilter\").addEventListener(\"change\", renderMainTable);\n\n            document.getElementById(\"inTok\").addEventListener(\"input\", renderCostTable);\n            document.getElementById(\"outTok\").addEventListener(\"input\", renderCostTable);\n            document.getElementById(\"categoryFilter\").addEventListener(\"change\", renderCostTable);\n\n            document.getElementById(\"reloadBtn\").addEventListener(\"click\", loadData);\n\n            document.getElementById(\"th-id\").addEventListener(\"click\", () => sortTable('id'));\n            document.getElementById(\"th-input\").addEventListener(\"click\", () => sortTable('input'));\n            document.getElementById(\"th-output\").addEventListener(\"click\", () => sortTable('output'));\n            document.getElementById(\"th-context\").addEventListener(\"click\", () => sortTable('context_length'));\n\n            const calcModal = document.getElementById(\"calcModal\");\n            document.getElementById(\"openCalcBtn\").addEventListener(\"click\", () => {\n                calcModal.style.display = \"flex\";\n                renderCostTable();\n            });\n\n            document.getElementById(\"closeCalcBtn\").addEventListener(\"click\", () => {\n                calcModal.style.display = \"none\";\n            });\n\n            calcModal.addEventListener(\"click\", (e) => {\n                if (e.target === calcModal) calcModal.style.display = \"none\";\n            });\n        }\n\n        function initApp() {\n            setupEventListeners();\n            loadData();\n        }\n\n        if (document.readyState === \"loading\") {\n            document.addEventListener(\"DOMContentLoaded\", initApp);\n        } else {\n            initApp();\n        }\n    })();\n    <\/script>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Understanding AI Model Pricing Through OpenRouter One of the biggest advantages of using OpenRouter.ai is that it provides a single API for accessing hundreds of AI models from leading providers including OpenAI, Anthropic, Google, xAI, Qwen, DeepSeek, Mistral, and many others. Rather than maintaining separate accounts and integrations for each AI vendor, developers can compare&#8230;<\/p>\n","protected":false},"author":2,"featured_media":521103,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","ngg_post_thumbnail":0,"episode_type":"","audio_file":"","podmotor_file_id":"","podmotor_episode_id":"","cover_image":"","cover_image_id":"","duration":"","filesize":"","filesize_raw":"","date_recorded":"","explicit":"","block":"","itunes_episode_number":"","itunes_title":"","itunes_season_number":"","itunes_episode_type":"","_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-521255","page","type-page","status-publish","has-post-thumbnail","hentry"],"taxonomy_info":[],"featured_image_src_large":["https:\/\/jorgep.com\/blog\/wp-content\/uploads\/FeaturedImage-TokenEcomonics.jpg",1000,375,false],"author_info":{"display_name":"Jorge Pereira","author_link":"https:\/\/jorgep.com\/blog\/author\/jorge\/"},"comment_info":0,"_links":{"self":[{"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/pages\/521255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/comments?post=521255"}],"version-history":[{"count":50,"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/pages\/521255\/revisions"}],"predecessor-version":[{"id":521509,"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/pages\/521255\/revisions\/521509"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/media\/521103"}],"wp:attachment":[{"href":"https:\/\/jorgep.com\/blog\/wp-json\/wp\/v2\/media?parent=521255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}