<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.simtx.net/index.php?action=history&amp;feed=atom&amp;title=SimTX_API_v24%2FDevice_login</id>
	<title>SimTX API v24/Device login - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.simtx.net/index.php?action=history&amp;feed=atom&amp;title=SimTX_API_v24%2FDevice_login"/>
	<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;action=history"/>
	<updated>2026-11-05T01:36:13Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;diff=2127&amp;oldid=prev</id>
		<title>Clanker: Archive the v24 protocol reference: use the v24 templates, links and categories</title>
		<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;diff=2127&amp;oldid=prev"/>
		<updated>2026-10-24T16:13:37Z</updated>

		<summary type="html">&lt;p&gt;Archive the v24 protocol reference: use the v24 templates, links and categories&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:13, 24 October 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{SimTX API navigation}}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24 &lt;/ins&gt;navigation}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&#039;&#039;&#039;Device login&#039;&#039;&#039; is the sign-in flow for software that cannot, or should not, handle a SimTX password itself: desktop applications, command-line tools and headless bridges. The software shows the user a short code, the user approves it in a browser while signed in to SimTX, and the software receives an [[SimTX API/Account service#Credential formats|access and refresh credential]].&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&#039;&#039;&#039;Device login&#039;&#039;&#039; is the sign-in flow for software that cannot, or should not, handle a SimTX password itself: desktop applications, command-line tools and headless bridges. The software shows the user a short code, the user approves it in a browser while signed in to SimTX, and the software receives an [[SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24&lt;/ins&gt;/Account service#Credential formats|access and refresh credential]].&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The flow is modelled on the OAuth 2.0 device authorization grant (RFC 8628), with two differences: requests and responses are JSON rather than form-encoded, and the endpoint and field names are SimTX&amp;#039;s own. Generic OAuth libraries will therefore not work without adaptation.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;The flow is modelled on the OAuth 2.0 device authorization grant (RFC 8628), with two differences: requests and responses are JSON rather than form-encoded, and the endpoint and field names are SimTX&amp;#039;s own. Generic OAuth libraries will therefore not work without adaptation.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Software that only receives does not need to sign in at all. Bots that run unattended should normally use a personal credential instead (see [[SimTX API/Account service#Authentication|Authentication]]).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Software that only receives does not need to sign in at all. Bots that run unattended should normally use a personal credential instead (see [[SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24&lt;/ins&gt;/Account service#Authentication|Authentication]]).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Sequence ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Sequence ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l38&quot;&gt;Line 38:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 38:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;clientName&amp;lt;/code&amp;gt; || string || No || Name shown to the user on the approval page and in their device list. Truncated to 80 characters. Defaults to &amp;lt;code&amp;gt;SimTX client&amp;lt;/code&amp;gt; when blank.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;clientName&amp;lt;/code&amp;gt; || string || No || Name shown to the user on the approval page and in their device list. Truncated to 80 characters. Defaults to &amp;lt;code&amp;gt;SimTX client&amp;lt;/code&amp;gt; when blank.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;scope&amp;lt;/code&amp;gt; || string || No || Space-separated list of [[SimTX API/Permissions|permission identifiers]] the credential may use. An empty or missing scope requests every permission the account holds at the moment of approval. Unknown identifiers are rejected with &amp;lt;code&amp;gt;400 scope_invalid&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;lt;code&amp;gt;scope&amp;lt;/code&amp;gt; || string || No || Space-separated list of [[SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24&lt;/ins&gt;/Permissions|permission identifiers]] the credential may use. An empty or missing scope requests every permission the account holds at the moment of approval. Unknown identifiers are rejected with &amp;lt;code&amp;gt;400 scope_invalid&amp;lt;/code&amp;gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l185&quot;&gt;Line 185:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 185:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== See also ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== See also ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[SimTX API/Account service]]: errors, credential formats and rate limits.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24&lt;/ins&gt;/Account service]]: errors, credential formats and rate limits.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[SimTX API/Game tickets]]: the next step for a client that wants to transmit.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24&lt;/ins&gt;/Game tickets]]: the next step for a client that wants to transmit.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{SimTX API navbox}}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{{SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24 &lt;/ins&gt;navbox}}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:SimTX API]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24&lt;/ins&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:SimTX API account service]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:SimTX API &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;v24 &lt;/ins&gt;account service]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Clanker</name></author>
	</entry>
	<entry>
		<id>https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;diff=2102&amp;oldid=prev</id>
		<title>Clanker: Clanker moved page SimTX API/Device login to SimTX API v24/Device login: Archive the v24 protocol reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;diff=2102&amp;oldid=prev"/>
		<updated>2026-10-24T16:12:20Z</updated>

		<summary type="html">&lt;p&gt;Clanker moved page &lt;a href=&quot;/index.php/SimTX_API/Device_login&quot; title=&quot;SimTX API/Device login&quot;&gt;SimTX API/Device login&lt;/a&gt; to &lt;a href=&quot;/index.php/SimTX_API_v24/Device_login&quot; title=&quot;SimTX API v24/Device login&quot;&gt;SimTX API v24/Device login&lt;/a&gt;: Archive the v24 protocol reference&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:12, 24 October 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Clanker</name></author>
	</entry>
	<entry>
		<id>https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;diff=1997&amp;oldid=prev</id>
		<title>Clanker: SimTX API documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API_v24/Device_login&amp;diff=1997&amp;oldid=prev"/>
		<updated>2026-10-24T09:50:19Z</updated>

		<summary type="html">&lt;p&gt;SimTX API documentation&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SimTX API navigation}}&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Device login&amp;#039;&amp;#039;&amp;#039; is the sign-in flow for software that cannot, or should not, handle a SimTX password itself: desktop applications, command-line tools and headless bridges. The software shows the user a short code, the user approves it in a browser while signed in to SimTX, and the software receives an [[SimTX API/Account service#Credential formats|access and refresh credential]].&lt;br /&gt;
&lt;br /&gt;
The flow is modelled on the OAuth 2.0 device authorization grant (RFC 8628), with two differences: requests and responses are JSON rather than form-encoded, and the endpoint and field names are SimTX&amp;#039;s own. Generic OAuth libraries will therefore not work without adaptation.&lt;br /&gt;
&lt;br /&gt;
Software that only receives does not need to sign in at all. Bots that run unattended should normally use a personal credential instead (see [[SimTX API/Account service#Authentication|Authentication]]).&lt;br /&gt;
&lt;br /&gt;
== Sequence ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
 Client                          auth.simtx.net                    User&amp;#039;s browser&lt;br /&gt;
   |  POST /device/authorizations      |                                  |&lt;br /&gt;
   |----------------------------------&amp;gt;|                                  |&lt;br /&gt;
   |  201 deviceCode, userCode, URI    |                                  |&lt;br /&gt;
   |&amp;lt;----------------------------------|                                  |&lt;br /&gt;
   |  show userCode, open URI -------------------------------------------&amp;gt;|&lt;br /&gt;
   |                                   |   user signs in and approves     |&lt;br /&gt;
   |  POST /device/token  (every 5 s)  |&amp;lt;---------------------------------|&lt;br /&gt;
   |----------------------------------&amp;gt;|                                  |&lt;br /&gt;
   |  400 authorization_pending        |                                  |&lt;br /&gt;
   |&amp;lt;----------------------------------|                                  |&lt;br /&gt;
   |  POST /device/token               |                                  |&lt;br /&gt;
   |----------------------------------&amp;gt;|                                  |&lt;br /&gt;
   |  200 access + refresh credential  |                                  |&lt;br /&gt;
   |&amp;lt;----------------------------------|                                  |&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Starting a login ==&lt;br /&gt;
&amp;lt;code&amp;gt;POST /api/v1/device/authorizations&amp;lt;/code&amp;gt;. No authentication.&lt;br /&gt;
&lt;br /&gt;
=== Request ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{ &amp;quot;clientName&amp;quot;: &amp;quot;Example SDR Client&amp;quot;, &amp;quot;scope&amp;quot;: &amp;quot;game.transmit&amp;quot; }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Type !! Required !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;clientName&amp;lt;/code&amp;gt; || string || No || Name shown to the user on the approval page and in their device list. Truncated to 80 characters. Defaults to &amp;lt;code&amp;gt;SimTX client&amp;lt;/code&amp;gt; when blank.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;scope&amp;lt;/code&amp;gt; || string || No || Space-separated list of [[SimTX API/Permissions|permission identifiers]] the credential may use. An empty or missing scope requests every permission the account holds at the moment of approval. Unknown identifiers are rejected with &amp;lt;code&amp;gt;400 scope_invalid&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Request the smallest scope that does the job. A transmitter needs &amp;lt;code&amp;gt;game.transmit&amp;lt;/code&amp;gt;. A tool that publishes extensions needs &amp;lt;code&amp;gt;catalog.publish&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Response ===&lt;br /&gt;
&amp;lt;code&amp;gt;201 Created&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;deviceCode&amp;quot;: &amp;quot;stx_dc1_9a1f…&amp;quot;,&lt;br /&gt;
  &amp;quot;userCode&amp;quot;: &amp;quot;QZ7K-M4TP&amp;quot;,&lt;br /&gt;
  &amp;quot;verificationUri&amp;quot;: &amp;quot;https://auth.simtx.net/device&amp;quot;,&lt;br /&gt;
  &amp;quot;verificationUriComplete&amp;quot;: &amp;quot;https://auth.simtx.net/device?code=QZ7K-M4TP&amp;quot;,&lt;br /&gt;
  &amp;quot;expiresIn&amp;quot;: 600,&lt;br /&gt;
  &amp;quot;interval&amp;quot;: 5,&lt;br /&gt;
  &amp;quot;expiresAt&amp;quot;: &amp;quot;2026-10-24T12:10:00Z&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;deviceCode&amp;lt;/code&amp;gt; || string || Secret used to poll for the result. Keep it private; do not show it to the user.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;userCode&amp;lt;/code&amp;gt; || string || Code the user confirms in the browser.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;verificationUri&amp;lt;/code&amp;gt; || string || Page where the user types the code.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;verificationUriComplete&amp;lt;/code&amp;gt; || string || Same page with the code pre-filled. Open this one if the client can launch a browser.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;expiresIn&amp;lt;/code&amp;gt; || integer || Seconds until the device code expires (600).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;interval&amp;lt;/code&amp;gt; || integer || Minimum seconds between polls (5).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;expiresAt&amp;lt;/code&amp;gt; || string || Absolute expiry time.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Display &amp;lt;code&amp;gt;userCode&amp;lt;/code&amp;gt; prominently and open &amp;lt;code&amp;gt;verificationUriComplete&amp;lt;/code&amp;gt;. The user can then compare the code on the page with the code in the application before approving.&lt;br /&gt;
&lt;br /&gt;
== Polling for credentials ==&lt;br /&gt;
&amp;lt;code&amp;gt;POST /api/v1/device/token&amp;lt;/code&amp;gt;. No authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{ &amp;quot;deviceCode&amp;quot;: &amp;quot;stx_dc1_9a1f…&amp;quot; }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Success ===&lt;br /&gt;
&amp;lt;code&amp;gt;200 OK&amp;lt;/code&amp;gt; with a credential pair:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;accessCredential&amp;quot;: &amp;quot;stx_at1_5c0e…&amp;quot;,&lt;br /&gt;
  &amp;quot;refreshCredential&amp;quot;: &amp;quot;stx_rt1_b77d…&amp;quot;,&lt;br /&gt;
  &amp;quot;credentialType&amp;quot;: &amp;quot;Bearer&amp;quot;,&lt;br /&gt;
  &amp;quot;expiresIn&amp;quot;: 600,&lt;br /&gt;
  &amp;quot;scope&amp;quot;: &amp;quot;game.transmit&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Type !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;accessCredential&amp;lt;/code&amp;gt; || string || Bearer credential, valid for &amp;lt;code&amp;gt;expiresIn&amp;lt;/code&amp;gt; seconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;refreshCredential&amp;lt;/code&amp;gt; || string || Used once to obtain the next pair.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;credentialType&amp;lt;/code&amp;gt; || string || Always &amp;lt;code&amp;gt;Bearer&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;expiresIn&amp;lt;/code&amp;gt; || integer || Access credential lifetime in seconds (600).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;scope&amp;lt;/code&amp;gt; || string || Space-separated scopes actually granted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A device code can be exchanged exactly once. Polling again after success returns &amp;lt;code&amp;gt;access_denied&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Not ready yet ===&lt;br /&gt;
Until the user acts, the service answers &amp;lt;code&amp;gt;400&amp;lt;/code&amp;gt; with one of the following codes. Every one of these responses includes the interval the client must now use, as a string, in &amp;lt;code&amp;gt;fieldErrors.interval&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &amp;lt;code&amp;gt;code&amp;lt;/code&amp;gt; !! Meaning !! Client action&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;authorization_pending&amp;lt;/code&amp;gt; || The user has not approved or denied yet. || Wait &amp;lt;code&amp;gt;interval&amp;lt;/code&amp;gt; seconds and poll again.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;slow_down&amp;lt;/code&amp;gt; || The poll arrived sooner than &amp;lt;code&amp;gt;interval&amp;lt;/code&amp;gt; seconds after the previous one. The interval has been increased by 5 seconds. || Adopt &amp;lt;code&amp;gt;fieldErrors.interval&amp;lt;/code&amp;gt; for all later polls.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;expired_token&amp;lt;/code&amp;gt; || Ten minutes have passed. || Start a new login.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;access_denied&amp;lt;/code&amp;gt; || The user denied the request, or the code was already exchanged. || Stop.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;invalid_grant&amp;lt;/code&amp;gt; || The device code is unknown. || Start a new login.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A client that ignores &amp;lt;code&amp;gt;slow_down&amp;lt;/code&amp;gt; and keeps its old pace is told to slow down on every single poll, and each warning adds another five seconds. Such a client never receives credentials. Read the interval from the response.&lt;br /&gt;
&lt;br /&gt;
== Refreshing ==&lt;br /&gt;
&amp;lt;code&amp;gt;POST /api/v1/device/refresh&amp;lt;/code&amp;gt;. No authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{ &amp;quot;refreshCredential&amp;quot;: &amp;quot;stx_rt1_b77d…&amp;quot; }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On success the response is &amp;lt;code&amp;gt;200 OK&amp;lt;/code&amp;gt; with a new credential pair in the same format as above. &amp;#039;&amp;#039;&amp;#039;The refresh credential rotates on every use.&amp;#039;&amp;#039;&amp;#039; Store the new one immediately and discard the old one.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! HTTP !! &amp;lt;code&amp;gt;code&amp;lt;/code&amp;gt; !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| 401 || &amp;lt;code&amp;gt;invalid_grant&amp;lt;/code&amp;gt; || The refresh credential is unknown, expired, or its device session was revoked. Sign in again.&lt;br /&gt;
|-&lt;br /&gt;
| 401 || &amp;lt;code&amp;gt;refresh_reuse_detected&amp;lt;/code&amp;gt; || A refresh credential that had already been used was presented again. The service treats this as theft and revokes the whole device session. Sign in again.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Refresh credentials expire after 30 days without use and 180 days after the original sign-in, whichever comes first.&lt;br /&gt;
&lt;br /&gt;
== Recommended client behaviour ==&lt;br /&gt;
# On start-up, load the stored refresh credential. If there is none, run device login.&lt;br /&gt;
# Refresh to obtain an access credential. Keep the access credential in memory.&lt;br /&gt;
# Refresh again when fewer than about 30 seconds of the access credential remain.&lt;br /&gt;
# When any endpoint answers &amp;lt;code&amp;gt;401 credential_invalid&amp;lt;/code&amp;gt;, refresh once and repeat the request. If the refresh fails, delete the stored credential and run device login.&lt;br /&gt;
# Serialise refreshes. Two threads refreshing with the same refresh credential at once will trigger &amp;lt;code&amp;gt;refresh_reuse_detected&amp;lt;/code&amp;gt;, and the user will have to sign in again.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
A complete login with &amp;lt;code&amp;gt;curl&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;jq&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
AUTH=https://auth.simtx.net&lt;br /&gt;
&lt;br /&gt;
start=$(curl -s -X POST &amp;quot;$AUTH/api/v1/device/authorizations&amp;quot; \&lt;br /&gt;
  -H &amp;#039;Content-Type: application/json&amp;#039; \&lt;br /&gt;
  -d &amp;#039;{&amp;quot;clientName&amp;quot;:&amp;quot;curl demo&amp;quot;,&amp;quot;scope&amp;quot;:&amp;quot;game.transmit&amp;quot;}&amp;#039;)&lt;br /&gt;
device=$(jq -r .deviceCode &amp;lt;&amp;lt;&amp;lt;&amp;quot;$start&amp;quot;)&lt;br /&gt;
interval=$(jq -r .interval &amp;lt;&amp;lt;&amp;lt;&amp;quot;$start&amp;quot;)&lt;br /&gt;
echo &amp;quot;Open $(jq -r .verificationUriComplete &amp;lt;&amp;lt;&amp;lt;&amp;quot;$start&amp;quot;) and confirm $(jq -r .userCode &amp;lt;&amp;lt;&amp;lt;&amp;quot;$start&amp;quot;)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
while sleep &amp;quot;$interval&amp;quot;; do&lt;br /&gt;
  reply=$(curl -s -X POST &amp;quot;$AUTH/api/v1/device/token&amp;quot; \&lt;br /&gt;
    -H &amp;#039;Content-Type: application/json&amp;#039; -d &amp;quot;{\&amp;quot;deviceCode\&amp;quot;:\&amp;quot;$device\&amp;quot;}&amp;quot;)&lt;br /&gt;
  case $(jq -r &amp;#039;.code // &amp;quot;ok&amp;quot;&amp;#039; &amp;lt;&amp;lt;&amp;lt;&amp;quot;$reply&amp;quot;) in&lt;br /&gt;
    ok) jq . &amp;lt;&amp;lt;&amp;lt;&amp;quot;$reply&amp;quot;; break ;;&lt;br /&gt;
    authorization_pending) ;;&lt;br /&gt;
    slow_down) interval=$(jq -r .fieldErrors.interval &amp;lt;&amp;lt;&amp;lt;&amp;quot;$reply&amp;quot;) ;;&lt;br /&gt;
    *) echo &amp;quot;login failed: $reply&amp;quot;; exit 1 ;;&lt;br /&gt;
  esac&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[SimTX API/Account service]]: errors, credential formats and rate limits.&lt;br /&gt;
* [[SimTX API/Game tickets]]: the next step for a client that wants to transmit.&lt;br /&gt;
&lt;br /&gt;
{{SimTX API navbox}}&lt;br /&gt;
[[Category:SimTX API]]&lt;br /&gt;
[[Category:SimTX API account service]]&lt;/div&gt;</summary>
		<author><name>Clanker</name></author>
	</entry>
</feed>