This is the AUTH V1 device flow, and V1 is being retired — apps on it are expected to stop working around April 2027. New integrations should use the AUTH V2 device flow, which implements RFC 8628 and works with stock OAuth libraries, and existing ones should plan to move via Migrating from V1 to V2. The two flows are not interchangeable — a V1 app cannot call the V2 endpoints, and a V2 app cannot use this one.
client_secret and no redirect URI required.
After the user authorizes, the device receives an access_token and behaves identically to an OAuth client from that point on.
Steps
Request a device code
GET /oauth/pin?client_id=… returns:user_code to the user. expires_in is 15 minutes; interval is 5 seconds (your polling cadence).device_code is returned as the literal string "DEVICE_CODE" — it’s a placeholder field kept for OAuth 2.0 Device Authorization Grant response-shape compatibility. Clients only need user_code. You can ignore device_code entirely.The response also includes a
verification_url key with the same value, kept as an alias. Read verification_uri — that’s the RFC 8628 §3.2 spelling.Display the code and instructions
Tell the user: “Go to simkl.com/pin and enter
ABCDE.” Render the code in a large, easy-to-read style — it’s typed by hand on a phone.Poll for the result
GET /oauth/pin/{USER_CODE}?client_id=… every interval seconds. Two response shapes:Stop polling as soon as you receive the
access_token. After successful authorization the server deletes the code; if you keep polling on the deleted (or any unknown) user_code, this endpoint falls through to the create-a-new-code branch and you’ll get back the same shape as GET /oauth/pin — including a brand-new user_code different from the one you polled. Detect any response containing device_code as “the original code is gone” and stop.Store the token and stop polling
Save the
access_token securely. From here on, the device works like any OAuth client — send Authorization: Bearer <access_token> on every authenticated request. Tokens are long-lived — the token-mint response advertises expires_in: 157680000 (about 5 years), and there’s no refresh-token grant. They only stop working when the user revokes your app from Connected Apps settings; on the next 401, restart the PIN flow.Why PIN vs OAuth?
See Set up authentication for the V2 setup path, including the device flow that replaces this one.
See also
Set up authentication
The V2 setup path, including the device flow that replaces this one.
OAuth 2.0 flow
The alternative for browsers, mobile, and desktop — token in ~5 seconds.
GET /oauth/pin
Endpoint reference — request a
user_code.GET /oauth/pin/{USER_CODE}
Endpoint reference — poll for the access token.