Skip to content

Authentication ​

Almost every ubi-services call needs a ticket and a session ID. Both come from POST /v3/profiles/sessions. The ticket is not a global bearer token — it is bound to the Ubi-AppId used when it was issued. Switching apps is ticket exchange, not a second password login.

1. POST /v3/profiles/sessions     Basic + AppId A
2. ticket set            → full session
   twoFactorAuthenticationTicket set, ticket null
                         → 2FA ticket (limited scope as ubi_v1 t=…)
                           or complete 2FA with Ubi_2fa_v1 t=… + ubi-2facode
3. GET  /v3/users/me              ubi_v1 t=ticket, AppId A
4. POST /v3/profiles/sessions     ubi_v1 t=ticket, AppId B
5. Scoped Session for AppId B

Password login ​

Send HTTP Basic where the user-info is email:password, then Base64.

Authorization: Basic {base64(email + ':' + password)}

Pair it with an app ID. The usual first hop is Main Auth / uplay mobile:

4391c956-8943-48eb-8859-07b0778f47b9

Full request/response types: Create session.

Keep the password off disk. Prefer exchanging an existing ticket, or using rememberMeTicket when you already have one, over storing the password.

Ticket ​

After a successful login, every follow-up request uses:

Authorization: ubi_v1 t={ticket}
Ubi-SessionId: {sessionId}

Official clients often send Ubi_v1 (capital U). Both forms work.

sessionId is a separate UUID from the session payload. Some endpoints tolerate a missing session header; most official clients send both.

Remember-me ​

The session payload may include rememberMeTicket. Treat it as a long-lived refresh credential for the same app ID. Re-login with it the same way you would a normal ticket exchange if you are staying on that app; if the server rejects it, fall back to password (and 2FA).

Two-factor ​

HTTP 200 does not mean you have a full ticket

When login returns 200 with ticket: null and a populated twoFactorAuthenticationTicket, 2FA is enabled on the account. That value is still a credential, but it is not a full ticket. Scope and access are limited until 2FA is completed and a real ticket is issued.

Use the 2FA ticket directly ​

Send it with the same scheme as a normal ticket. This works for a narrower set of calls (pre-2FA / limited scope). It is not a substitute for ticket exchange or for endpoints that require a completed login.

Authorization: ubi_v1 t={twoFactorAuthenticationTicket}

Do not treat body.ticket and body.twoFactorAuthenticationTicket as interchangeable.

Complete 2FA ​

Same path as create session. This exchanges the 2FA ticket for a full Session.

http
POST https://public-ubiservices.ubi.com/v3/profiles/sessions
Authorization: Ubi_2fa_v1 t={twoFactorAuthenticationTicket}
Ubi-AppId: {same app id as the password login}
Ubi-RequestedPlatformType: uplay
Content-Type: application/json
ubi-2facode: {6-digit code}
ts
type CompleteTwoFactorBody = {
  trustedDevice: null
}

ubi-2facode is a six-digit TOTP / email code. Scheme is Ubi_2fa_v1 or ubi_2fa_v1 — not ubi_v1. Body is { "trustedDevice": null } or { "rememberMe": true }. After this succeeds, use the returned ticket and sessionId.

Check current 2FA configuration once you have a full ticket:

Setup / teardown: Account management.

Extracting userId from a ticket ​

If you have a ticket but not the user UUID:

userId and uplay profileId are often the same UUID on PC, but do not assume that once Xbox / PSN / Epic / Steam profiles are linked. Always read linked profiles.

What not to do ​

  • Do not send a 2FA ticket where a full ticket is required. Scope and access are limited.
  • Do not send one ticket with a random other Ubi-AppId and expect it to work. Exchange first.
  • Do not treat CERT2 / UAT tickets as valid on PROD (environments).
  • Do not hammer /sessions with credential lists. That is abuse, not an API client.

Unofficial community documentation. Not affiliated with Ubisoft.