xsapi

package module
v2.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2026 License: MIT Imports: 22 Imported by: 0

README

go-xsapi

Go Reference

A Go library for communicating with Xbox Live API.

Azure_Bit_Gopher.png

Example

This code demonstrates Device Authorization Code Flow to retrieve access token, and interacts with some of the API endpoints available in Xbox Live.

// Notify for Ctrl+C and other interrupt signals so the user can abort
// the device authorization flow or other operations at any time.
signals, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()

// Use the Device Authorization Flow to sign in to a Microsoft Account.
da, err := MinecraftAndroid.DeviceAuth(signals)
if err != nil {
	panic(fmt.Sprintf("error requesting device authorization flow: %s", err))
}

// We print out the verification URI and the user code to [os.Stderr]
// so it doesn't need to be captured by Output: line in this example.
_, _ = fmt.Fprintf(os.Stderr,
	"Sign in to your Microsoft Account at %s using the code %s.",
	da.VerificationURI, da.UserCode,
)

// Make a context for polling the access token while the user completes sign-in.
// In this case, we allow one minute to complete login (you may configure a longer timeout).
pollCtx, cancel := context.WithTimeout(signals, time.Minute)
defer cancel()
token, err := MinecraftAndroid.DeviceAccessToken(pollCtx, da)
if err != nil {
	panic(fmt.Sprintf("error polling access token in device authorization flow: %s", err))
}
// Use TokenSource so we can always use a valid token in fresh state.
msa := MinecraftAndroid.TokenSource(context.Background(), token)

// Make a SISU session using the Microsoft Account token source.
session := MinecraftAndroid.New(msa, nil)

// Log in to Xbox Live services using the SISU session.
client, err := NewClient(session)
if err != nil {
	panic(fmt.Sprintf("error creating API client: %s", err))
}
// Make sure to close the client when it's done.
defer func() {
	if err := client.Close(); err != nil {
		panic(fmt.Sprintf("error closing API client: %s", err))
	}
}()

// Use social (peoplehub) endpoint to search a user using the query.
ctx, cancel := context.WithTimeout(signals, time.Second*15)
defer cancel()
users, err := client.Social().Search(ctx, "Lactyy")
if err != nil {
	panic(fmt.Sprintf("error searching for users: %s", err))
}
if len(users) == 0 {
	panic("no users found")
}

// Use the first user present in the result.
user := users[0]
fmt.Println(user.GamerTag)

Contact

Discord Banner 2

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AcceptLanguage

func AcceptLanguage(tags []language.Tag) internal.RequestOption

AcceptLanguage returns a internal.RequestOption that appends the given language tags to the 'Accept-Language' header on outgoing requests, preserving any tags already present in the header.

func RequestHeader

func RequestHeader(key, value string) internal.RequestOption

RequestHeader returns a internal.RequestOption that sets a request header with the given name and value on outgoing requests.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a client set that aggregates API clients for each Xbox Live endpoint. It also implements http.RoundTripper to transparently authenticate outgoing requests with XSTS tokens and request signatures.

Example

ExampleClient demonstrates how we can communicate with various Xbox Live network services. It uses the SISU configuration dumped from Minecraft: Bedrock Edition for Android for authentication.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"os"
	"os/signal"
	"time"

	"github.com/df-mc/go-xsapi/v2/presence"
	"github.com/df-mc/go-xsapi/v2/xal"
	"github.com/df-mc/go-xsapi/v2/xal/sisu"
)

// ExampleClient demonstrates how we can communicate with various Xbox Live network services.
// It uses the SISU configuration dumped from Minecraft: Bedrock Edition for Android for authentication.
func main() {
	// Notify for Ctrl+C and other interrupt signals so the user can abort
	// the device authorization flow or other operations at any time.
	signals, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
	defer cancel()

	// Initiate Device Authorization Flow to sign in to a Microsoft Account.
	da, err := MinecraftAndroid.DeviceAuth(signals)
	if err != nil {
		panic(fmt.Sprintf("error requesting device authorization flow: %s", err))
	}

	log.Printf(
		"Sign in to your Microsoft Account at %s using the code %s.",
		da.VerificationURI, da.UserCode,
	)

	// Poll for the access token while the user completes the browser sign-in.
	// The timeout is set to one minute. Increase if you need more time.
	pollCtx, cancel := context.WithTimeout(signals, time.Minute)
	defer cancel()
	token, err := MinecraftAndroid.DeviceAccessToken(pollCtx, da)
	if err != nil {
		panic(fmt.Sprintf("error polling access token in device authorization flow: %s", err))
	}
	// Use TokenSource so we can always use a valid token in fresh state.
	msa := MinecraftAndroid.TokenSource(context.Background(), token)

	// Make a SISU session using the Microsoft Account token source.
	session := MinecraftAndroid.New(msa, nil)

	// Request a XASU (Xbox Authentication Services for User) token using the SISU authorization endpoint.
	if _, err := session.UserToken(signals); err != nil {
		var acct *sisu.AccountRequiredError
		if errors.As(err, &acct) {
			log.Panicf("You need to create an Xbox Live account at: %s", acct.SignupURL)
		}
		panic(fmt.Sprintf("error requesting user token: %s", err))
	}

	// Log in to Xbox Live services using the SISU session.
	client, err := NewClient(session)
	if err != nil {
		panic(fmt.Sprintf("error creating API client: %s", err))
	}
	// Make sure to close the client when it's done.
	defer func() {
		if err := client.Close(); err != nil {
			panic(fmt.Sprintf("error closing API client: %s", err))
		}
	}()

	// Appear online in the social network.
	if err := client.Presence().Update(signals, presence.TitleRequest{
		State: presence.StateActive,
	}); err != nil {
		panic(fmt.Sprintf("error updating presence: %s", err))
	}

	// Use the social (peoplehub) endpoint to search a user using the query.
	ctx, cancel := context.WithTimeout(signals, time.Second*15)
	defer cancel()
	users, err := client.Social().Search(ctx, "Lactyy")
	if err != nil {
		panic(fmt.Sprintf("error searching for users: %s", err))
	}
	if len(users) == 0 {
		panic("no users found")
	}

	// Use the first user present in the result.
	user := users[0]
	fmt.Println(user.GamerTag)
}

// MinecraftAndroid is the SISU configuration for Minecraft: Bedrock Edition on Android.
//
// It provides all the parameters needed to authenticate a user with a Microsoft Account
// and authorize them for Xbox Live services using the SISU endpoints.
//
// Note that ClientID, RedirectURI, and other title-specific fields are fixed values tied
// to the Minecraft title. Do not modify them unless you are targeting a different title.
var MinecraftAndroid = sisu.Config{
	Config: xal.Config{
		// This indicates the device is running Android 13.
		Device: xal.Device{
			Type:    xal.DeviceTypeAndroid,
			Version: "13",
		},
		UserAgent: "XAL Android 2025.04.20250326.000",
		TitleID:   1739947436,
		Sandbox:   "RETAIL", // Usually 'RETAIL' for most games available in the market
	},

	// Those fields are title-specific and cannot be easily changed.
	// Treat them like constants that are specific to the title being authenticated for the user.
	ClientID:    "0000000048183522",               // Client ID used for authenticating and authorizing with Xbox Live
	RedirectURI: "ms-xal-0000000048183522://auth", // Used for Authorization Code Flow
}

func NewClient

func NewClient(src TokenSource) (*Client, error)

NewClient creates a new Client using a default ClientConfig and a 15-second timeout for the initial login. For more control over the configuration, use ClientConfig.New directly.

func (*Client) Close

func (c *Client) Close() error

Close closes all underlying API clients with a 15-second timeout. For a context-aware variant, use Client.CloseContext.

func (*Client) CloseContext

func (c *Client) CloseContext(ctx context.Context) error

CloseContext closes all underlying API clients using the given context. Once closed, the Client cannot be reused as it also disconnects from WebSocket-based services such as RTA.

CloseContext also removes the authenticated title's current Xbox Live presence via presence.Client.Remove. This is intentional: shutting down the client is treated as the title closing, so the presence is cleared immediately instead of waiting for it to expire on the server.

Callers that want to release other resources without mutating presence should not call CloseContext.

func (*Client) HTTPClient

func (c *Client) HTTPClient() *http.Client

HTTPClient returns the underlying HTTP client that automatically authenticates outgoing requests via Client.RoundTrip.

func (*Client) Log

func (c *Client) Log() *slog.Logger

Log returns the slog.Logger configured via [ClientConfig.Logger].

func (*Client) MPSD

func (c *Client) MPSD() *mpsd.Client

MPSD returns the API client for the Xbox Live MPSD (Multiplayer Session Directory) API.

func (*Client) Presence

func (c *Client) Presence() *presence.Client

Presence returns the API client for the Xbox Live Presence API.

func (*Client) RTA

func (c *Client) RTA() *rta.Conn

RTA returns the connection to Xbox Live RTA (Real-Time Activity) services.

func (*Client) RoundTrip

func (c *Client) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper. It resolves an XSTS token and signature policy for the request URL using NSAL (Network Security Allow List), then sets the 'Authorization' and 'Signature' headers before forwarding the request to the underlying transport.

RoundTrip always consumes the request body, even on error, as required by the http.RoundTripper contract. The request is cloned before any headers are set to avoid mutating the original.

func (*Client) Social

func (c *Client) Social() *social.Client

Social returns the API client for the Xbox Live Social APIs.

func (*Client) TokenAndSignature

func (c *Client) TokenAndSignature(ctx context.Context, u *url.URL) (_ *xsts.Token, policy nsal.SignaturePolicy, _ error)

TokenAndSignature resolves an XSTS token and signature policy for the given URL using NSAL (Network Security Allow List). Title-scoped NSAL data takes priority over default data when matching the URL to an endpoint.

The returned signature policy may be used to sign a request via its Sign method. For most use cases, Client.HTTPClient handles this automatically.

TokenAndSignature is intended for external endpoints that require the XSTS token to be embedded directly in the request body, such as PlayFab's /Client/LoginWithXbox endpoint.

func (*Client) TokenSource

func (c *Client) TokenSource() TokenSource

TokenSource returns the TokenSource used by the client to supply XSTS tokens and the proof key for signing requests.

func (*Client) UserInfo

func (c *Client) UserInfo() xsts.UserInfo

UserInfo returns the profile information for the caller, including their XUID, display name, and other metadata. It is derived from the XSTS token that relies on the party 'http://xboxlive.com' and is not updated during the lifecycle of the Client.

type ClientConfig

type ClientConfig struct {
	// HTTPClient is the HTTP client used to make requests. If nil,
	// [http.DefaultClient] is used. The client is cloned internally,
	// so the original is never mutated.
	HTTPClient *http.Client

	// Logger is the logger used by the client set and its underlying API
	// clients. If nil, [slog.Default] is used.
	Logger *slog.Logger

	// RTADialer is used to establish a connection to Xbox Live RTA
	// (Real-Time Activity) services.
	RTADialer rta.Dialer
}

ClientConfig holds the configuration for creating a Client.

func (ClientConfig) New

func (config ClientConfig) New(ctx context.Context, src TokenSource) (*Client, error)

New creates a new Client using the given TokenSource and ClientConfig. The provided context governs the initial login, including requesting XSTS tokens, fetching NSAL data, and connecting to WebSocket services.

New clones the [ClientConfig.HTTPClient] internally so that the original client is never mutated. This means that passing http.DefaultClient or any shared http.Client is safe.

type TokenSource

type TokenSource interface {
	xsts.TokenSource
	xasd.TokenSource
}

TokenSource is the interface that supplies XSTS tokens and device tokens with the private key used to sign requests.

Directories

Path Synopsis
xal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL