Store the cookies from every response and send them back on every request. On Android with OkHttp, use a persistent CookieJar (for example PersistentCookieJar).The refresh call needs the refresh_token cookie, so a cookie store is the simplest option.
If the refresh also fails, send the user back to the login screen.
This also applies to the voucher and session calls: a valid api-key does not help if the request carries an expired token. Either refresh first, or don’t send the cookie on calls that only need the API key.
If several requests fail with 401 at the same time, refresh once and retry them all after it completes. The refresh token is single use, so two parallel refresh calls would make the second one fail.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"TuniMobile Integration API","description":"Sell TuniMobile recharge vouchers (Tunisie Telecom, Orange, Ooredoo) from your own application.","colors":{"primary":"#16A34A","light":"#07C983","dark":"#15803D"},"favicon":"https://mintcdn.com/tuni-mobile/Z828WuxAtlYeXtz_/favicon.svg?fit=max\u0026auto=format\u0026n=Z828WuxAtlYeXtz_\u0026q=85\u0026s=751b3784f11581568ccef74e925f1179","api":{"playground":{"display":"none"},"mdx":{"server":["https://apitest.tunimobile.com/v1","https://api.tunimobile.com/v1"]}},"navbar":{"primary":{"type":"button","label":"TuniMobile","href":"https://tunimobile.com"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"tuni-mobile","hasAudioNarration":false,"actualSubdomain":"tuni-mobile","customDomains":["docs.tunimobile.com"],"gitSource":{"type":"artifacts","owner":"prod","repo":"6ae21fe4ea96bbaeeb8784af","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":"","_id":"6ae21ffba70829123067bb16"},"chroma":{"latestBuiltDeploymentHistoryId":"6ae22000a70829123067bb6d","collectionId":"05866f62-ca31-443e-b395-f9b61dfd0860","liveDeploymentHistoryId":"6ae22000a70829123067bb6d","schemaVersion":"v3"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae2394a0ef2a112dc97d4d0","clientVersion":"0.0.4005","searchFilterCounts":[{"language":"default","tag":"Getting Started","count":2}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"basics/authentication","slug":"/basics/authentication","pageMetadata":{"title":"Authentication","description":"JWT access and refresh tokens delivered as cookies.","icon":"key","href":"/basics/authentication"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"JWT access and refresh tokens delivered as cookies.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{CodeBlock,Heading,Step,Steps,Tab,Table,Tabs,Tip,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Authentication uses a JWT access token and a refresh token, both delivered as `,_jsx(_components.strong,{children:`cookies`}),` by the `,_jsx(_components.a,{href:`/api/auth/login`,children:`login`}),` call:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Cookie`}),_jsx(_components.th,{children:`Content`}),_jsx(_components.th,{children:`Lifetime`}),_jsx(_components.th,{children:`Flags`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`BEARER`})}),_jsx(_components.td,{children:`JWT access token`}),_jsx(_components.td,{children:`1 hour`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`HttpOnly`}),`, `,_jsx(_components.code,{children:`Secure`}),`, `,_jsx(_components.code,{children:`SameSite=None`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`refresh_token`})}),_jsx(_components.td,{children:`Refresh token (single use)`}),_jsx(_components.td,{children:`30 days, extended each time it is used`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`HttpOnly`}),`, `,_jsx(_components.code,{children:`Secure`}),`, `,_jsx(_components.code,{children:`SameSite=None`})]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`The tokens are `,_jsx(_components.strong,{children:`not`}),` in the response body.`]}),`\n`,_jsx(Heading,{level:`2`,id:`sending-the-tokens`,children:`Sending the tokens`}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Cookie store (recommended)`,id:`cookie-store-recommended`,children:[_jsxs(_components.p,{children:[`Store the cookies from every response and send them back on every request. On Android with OkHttp, use a persistent `,_jsx(_components.code,{children:`CookieJar`}),` (for example `,_jsx(_components.code,{children:`PersistentCookieJar`}),`).`]}),_jsxs(_components.p,{children:[`The refresh call needs the `,_jsx(_components.code,{children:`refresh_token`}),` cookie, so a cookie store is the simplest option.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` cookies.txt`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -b`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` cookies.txt`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Content-Type: application/json\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -d`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"action\":\"get_credit\"}'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://apitest.tunimobile.com/v1/user/do_action`})}),`\n`]})})})]}),_jsxs(Tab,{title:`Authorization header`,id:`authorization-header`,children:[_jsxs(_components.p,{children:[`For the access token only: read the JWT from the `,_jsx(_components.code,{children:`Set-Cookie: BEARER=...`}),` header of the login response and send it as a bearer token.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer \u003cjwt>\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Content-Type: application/json\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -d`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"action\":\"get_credit\"}'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://apitest.tunimobile.com/v1/user/do_action`})}),`\n`]})})})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`expired-tokens`,children:`Expired tokens`}),`\n`,_jsx(_components.p,{children:`When the access token expires, any call that carries it returns:`}),`\n`,_jsx(CodeBlock,{filename:`401`,numberOfLines:`1`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{ `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"code\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`401`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"message\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Expired JWT Token\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`]})})}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Refresh`,children:_jsxs(_components.p,{children:[`Call `,_jsx(_components.a,{href:`/api/auth/refresh`,children:`Refresh the session`}),`.`]})}),_jsx(Step,{title:`Retry once`,children:_jsx(_components.p,{children:`Retry the original request once.`})}),_jsx(Step,{title:`Fall back to login`,children:_jsx(_components.p,{children:`If the refresh also fails, send the user back to the login screen.`})})]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`This also applies to the voucher and session calls: a valid `,_jsx(_components.code,{children:`api-key`}),` does not help if the request carries an expired token. Either refresh first, or don’t send the cookie on calls that only need the API key.`]})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`If several requests fail with `,_jsx(_components.code,{children:`401`}),` at the same time, refresh `,_jsx(_components.strong,{children:`once`}),` and retry them all after it completes. The refresh token is single use, so two parallel refresh calls would make the second one fail.`]})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Authentication","description":"JWT access and refresh tokens delivered as cookies.","icon":"key","href":"/basics/authentication"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Sending the tokens","slug":"sending-the-tokens","depth":2,"children":[]},{"title":"Expired tokens","slug":"expired-tokens","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"tuni-mobile","siteName":"TuniMobile Integration API","title":"Authentication - TuniMobile Integration API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-28T18:05:07.033Z","originalFileLocation":"basics/authentication.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"JWT access and refresh tokens delivered as cookies.\">\u003cmeta data-mint-head name=\"application-name\" content=\"TuniMobile Integration API\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Authentication - TuniMobile Integration API\">\u003cmeta data-mint-head property=\"og:description\" content=\"JWT access and refresh tokens delivered as cookies.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"TuniMobile Integration API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.tunimobile.com/basics/authentication\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://tuni-mobile.mintlify.app/_mintlify/api/og/v2?division=Basics\u0026amp;title=Authentication\u0026amp;description=JWT+access+and+refresh+tokens+delivered+as+cookies.\u0026amp;theme=df44427d4ddbca4dea795833\u0026amp;signature=1307fb01c5fa94b1d6c0c86a1abf54b510be2cd2ccffc5836af748dc94b648c4\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Authentication - TuniMobile Integration API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"JWT access and refresh tokens delivered as cookies.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://tuni-mobile.mintlify.app/_mintlify/api/og/v2?division=Basics\u0026amp;title=Authentication\u0026amp;description=JWT+access+and+refresh+tokens+delivered+as+cookies.\u0026amp;theme=df44427d4ddbca4dea795833\u0026amp;signature=1307fb01c5fa94b1d6c0c86a1abf54b510be2cd2ccffc5836af748dc94b648c4\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/tuni-mobile/hk79GHUBoQsFCvCv/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"TuniMobile Integration API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#16A34A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.tunimobile.com/basics/authentication\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/basics/authentication.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.tunimobile.com/#organization\",\"name\":\"TuniMobile Integration API\",\"url\":\"https://docs.tunimobile.com\"},{\"@type\":\"WebSite\",\"@id\":\"https://docs.tunimobile.com#website\",\"name\":\"TuniMobile Integration API\",\"url\":\"https://docs.tunimobile.com\",\"publisher\":{\"@id\":\"https://docs.tunimobile.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.tunimobile.com/basics/authentication#webpage\",\"url\":\"https://docs.tunimobile.com/basics/authentication\",\"name\":\"Authentication\",\"description\":\"JWT access and refresh tokens delivered as cookies.\",\"dateModified\":\"2026-10-28T18:05:07.033Z\",\"isPartOf\":{\"@id\":\"https://docs.tunimobile.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.tunimobile.com/basics/authentication#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.tunimobile.com/basics/authentication#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Basics\",\"item\":\"https://docs.tunimobile.com/basics/requests-and-responses\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Authentication\",\"item\":\"https://docs.tunimobile.com/basics/authentication\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.tunimobile.com/basics/authentication#article\",\"headline\":\"Authentication\",\"name\":\"Authentication\",\"description\":\"JWT access and refresh tokens delivered as cookies.\",\"url\":\"https://docs.tunimobile.com/basics/authentication\",\"mainEntityOfPage\":{\"@id\":\"https://docs.tunimobile.com/basics/authentication#webpage\"},\"dateModified\":\"2026-10-28T18:05:07.033Z\",\"publisher\":{\"@id\":\"https://docs.tunimobile.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.tunimobile.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"TuniMobile Integration API\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"TuniMobile Integration API","nav":{"global":null,"pages":[{"group":"Getting Started","pages":[{"title":"Introduction","icon":"house","href":"/index"},{"title":"Quickstart","icon":"rocket","href":"/quickstart"}]},{"group":"Basics","pages":[{"title":"Requests and responses","description":"Base URL, request format and the response envelope.","icon":"arrow-right-arrow-left","href":"/basics/requests-and-responses"},{"title":"Authentication","icon":"key","href":"/basics/authentication"},{"title":"Terminal API key","description":"Identify each printing device, and see which credential each endpoint needs.","icon":"mobile","href":"/basics/terminal-api-key"}]},{"group":"Authentication","pages":[{"title":"Log in","api":"POST /login_check","href":"/api/auth/login"},{"title":"Refresh the session","api":"POST /token/refresh","href":"/api/auth/refresh"},{"title":"Log out","api":"GET /user/logout","href":"/api/auth/logout"}]},{"group":"Account","pages":[{"title":"Get the profile","api":"POST /user/do_action","href":"/api/account/profile"},{"title":"Get the balance","api":"POST /user/do_action","href":"/api/account/balance"}]},{"group":"Terminal","pages":[{"title":"Register / check the terminal","api":"POST /terminal/do_action","href":"/api/terminal/register"}]},{"group":"Vouchers","pages":[{"title":"Generate a voucher","sidebarTitle":"Generate (printVoucher)","api":"POST /voucher/do_action","href":"/api/vouchers/generate"},{"title":"Confirm a printed voucher","sidebarTitle":"Confirm (confirmVoucher)","api":"POST /voucher/do_action","href":"/api/vouchers/confirm"},{"title":"Reprint an unconfirmed voucher","sidebarTitle":"Reprint (reprintVoucher)","api":"POST /voucher/do_action","href":"/api/vouchers/reprint"},{"title":"Print a duplicate of a confirmed voucher","sidebarTitle":"Duplicate (duplicateVoucher)","api":"POST /voucher/do_action","href":"/api/vouchers/duplicate"},{"title":"Confirm a reprint or duplicate","sidebarTitle":"Confirm reprint (confirmReprintVoucher)","api":"POST /voucher/do_action","href":"/api/vouchers/confirm-reprint"},{"title":"List the voucher history","sidebarTitle":"History","api":"POST /vouchers","href":"/api/vouchers/history"}]},{"group":"Sales sessions","pages":[{"title":"Open / close a sales session","sidebarTitle":"Close and open session","api":"POST /session/","href":"/api/sessions/rotate"}]},{"group":"Reference","pages":[{"title":"Voucher statuses","icon":"list-check","href":"/reference/voucher-statuses"},{"title":"Errors","icon":"triangle-exclamation","href":"/reference/errors"}]}]},"title":"Authentication - TuniMobile Integration API","buildId":"dpl_48qhjNLiu9iJQQSZJz9Fa2ihBbPH","deploymentId":"dpl_48qhjNLiu9iJQQSZJz9Fa2ihBbPH","dynamics":[],"chunks":[]}