A Swift package for retrieving EA Player IDs (nucleus_id, pid, personaId) from EA's Identity API.
⚠️ Note: Origin was officially shut down by EA in April 2025. This package uses EA gateway endpoints (gateway.ea.com).
EAIdentityKit provides a clean, Swift-native interface to EA's identity services. Use this package to:
- Retrieve a user's nucleus ID (pidId) - the master account identifier
- Retrieve a user's persona ID - the per-game/platform identifier
- Retrieve a user's EA ID - the public username visible to other players
- Validate and store EA OAuth access tokens securely
- macOS 12.0+ / iOS 15.0+ / tvOS 15.0+ / watchOS 8.0+
- Swift 5.7+
- Xcode 14.0+
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/yourusername/EAIdentityKit.git", from: "1.0.0")
]Or in Xcode:
- Go to File → Add Packages...
- Enter the repository URL
- Select the version and click Add Package
The package includes EAWebAuthenticator which presents EA's login page in a web view and automatically captures the token:
// macOS
let webAuth = EAWebAuthenticator()
let token = try await webAuth.authenticate(from: window)
// iOS
let token = try await webAuth.authenticate(from: viewController)
// Or use the EAClient convenience method
let client = EAClient()
let token = try await client.authenticateWithWeb(from: window)
let identity = try await client.getIdentity()The web authenticator has configurable delays for token extraction:
let webAuth = EAWebAuthenticator()
// Time to wait after account page loads before extracting token (default: 5 seconds)
webAuth.extractionDelay = 7.0
// Time to wait after login before redirecting to account page (default: 2 seconds)
webAuth.redirectDelay = 3.0
let token = try await webAuth.authenticate(from: window)If the web-based approach doesn't work, you can get a token manually:
From Browser:
- Go to ea.com and sign in
- Open Developer Tools (F12)
- Go to the Network tab
- Filter requests by
gateway.ea.com - Look for the
Authorizationheader in any request - Copy the token value (remove the
Bearerprefix)
From EA App (Windows): Use a network inspection tool like Fiddler or Wireshark to capture network traffic and find requests with Bearer tokens to EA's gateway.
import EAIdentityKit
// Initialize client with your token
let client = EAClient()
try await client.setToken("your_access_token_here")
// Get identity
let identity = try await client.getIdentity()
print("EA ID: \(identity.eaId)")
print("Nucleus ID: \(identity.pidId)")
print("Persona ID: \(identity.personaId)")let client = EAClient()
// Set and validate token
try await client.setToken("your_token")
// Get full identity
let identity = try await client.getIdentity()
// Or get specific IDs
let nucleusId = try await client.getNucleusId()
let personaId = try await client.getPersonaId()
let eaId = try await client.getEAId()let api = EAIdentityAPI(accessToken: "your_token_here")
// Get full identity
let identity = try await api.getFullIdentity()
// Or get specific data
let pidInfo = try await api.getPIDInfo()
let personaInfo = try await api.getPersonaInfo(pidId: pidInfo.pidId)let authenticator = EAAuthenticator()
// Validate and store a token
let isValid = try await authenticator.validateAndStore(token: "your_token")
// Test if token works
let works = try await authenticator.testToken("your_token")
// Get stored token later
if let token = authenticator.getStoredToken() {
let api = EAIdentityAPI(accessToken: token)
}// Check if there's a valid cached token
if let api = EAIdentityAPI.fromCache() {
let identity = try await api.getFullIdentity()
}import SwiftUI
import EAIdentityKit
struct ContentView: View {
@State private var identity: EAIdentity?
@State private var token = ""
var body: some View {
VStack {
if let identity = identity {
Text("EA ID: \(identity.eaId)")
Text("Nucleus ID: \(identity.pidId)")
} else {
SecureField("Access Token", text: $token)
Button("Fetch Identity") {
Task {
let api = EAIdentityAPI(accessToken: token)
identity = try? await api.getFullIdentity()
}
}
}
}
}
}import Combine
var cancellables = Set<AnyCancellable>()
let api = EAIdentityAPI(accessToken: token)
api.getFullIdentityPublisher()
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { completion in
if case .failure(let error) = completion {
print("Error: \(error)")
}
},
receiveValue: { identity in
print("EA ID: \(identity.eaId)")
}
)
.store(in: &cancellables)High-level client combining token management and identity fetching.
| Method | Description |
|---|---|
setToken(_:) |
Validate and store a token |
setTokenWithoutValidation(_:expiresIn:) |
Store token without validation |
testCurrentToken() |
Test if stored token works |
getIdentity() |
Get full identity |
getNucleusId() |
Get only nucleus ID |
getPersonaId() |
Get only persona ID |
getEAId() |
Get only EA ID (username) |
logout() |
Clear stored credentials |
Lower-level API client for direct API access.
| Method | Description |
|---|---|
getPIDInfo() |
Get nucleus ID and account details |
getPersonaInfo(pidId:) |
Get persona ID and EA ID |
getFullIdentity() |
Get complete identity information |
fromCache() |
Create API from cached token |
Web-based authenticator that captures tokens from EA's login flow.
| Method/Property | Description |
|---|---|
authenticate(from:) |
Present login and capture token |
present(from:) |
Present login (delegate-based) |
dismiss() |
Dismiss the login view |
extractionDelay |
Seconds to wait before token extraction (default: 5.0) |
redirectDelay |
Seconds to wait before redirecting to account page (default: 2.0) |
Handles token validation and storage.
| Method | Description |
|---|---|
validateAndStore(token:) |
Validate and store a token |
validateToken(_:) |
Check if token is valid |
testToken(_:) |
Test token against API |
getStoredToken() |
Get stored token |
storeToken(_:expiresIn:) |
Store token directly |
logout() |
Clear stored credentials |
| Model | Description |
|---|---|
EAIdentity |
Complete identity with pidId, personaId, eaId |
PIDInfo |
Detailed account information |
PersonaInfo |
Persona information (userId, personaId, eaId) |
TokenInfo |
Token validation response |
EACredentials |
Stored authentication credentials |
do {
let identity = try await client.getIdentity()
} catch EAAuthError.noToken {
// No token set - call setToken() first
} catch EAAuthError.invalidToken {
// Token is invalid or expired
} catch EAIdentityError.invalidToken {
// Token expired - get a new one
} catch EAIdentityError.rateLimited {
// Too many requests - wait and retry
} catch {
print("Error: \(error)")
}| Term | Description |
|---|---|
| pidId / nucleus_id | Master account identifier at EA's backend |
| personaId | Per-game or per-platform identifier |
| EAID / EA ID | Public username visible to other players |
A single EA account (pidId) can have multiple personas (personaId) across different platforms (PC, PlayStation, Xbox) or games.
- Token Security: Tokens are stored securely in the Keychain
- No Credentials Stored: The package never stores email/password
- Token Expiration: Tokens typically expire in 1 hour
- Terms of Service: Using undocumented APIs may violate EA's ToS
As of April 2025, EA has officially shut down the Origin client and its associated APIs. This package uses EA's gateway endpoints (gateway.ea.com). Automated OAuth authentication is not supported due to EA's strict redirect URI requirements.
This project is licensed under the MIT License - see the LICENSE file for details.
This package is not affiliated with or endorsed by Electronic Arts Inc. Use at your own risk. EA's APIs may change without notice.