Product that suits modern B2B Tech companies

Book Demo
B
Book demo call-to-action illustration
BACK
B

UKG Pro API authentication, architecture, and data access

Platform APIs
September 22, 2026
Summarise the blog with AI
Open in ChatGPT
Ask questions about this page
Open in Claude
Ask questions about this page

Key takeaways

  • UKG Pro runs two generations of API auth side by side: legacy per-product credentials (Basic auth with API keys, SOAP login tokens) and newer OAuth 2.0 client credentials from the Developer Console.
  • For system-to-system integrations, UKG requires client credentials wherever an endpoint supports them, and warns that named-user credentials in automation lead to throttling and account lockouts.
  • Token lifetimes differ by product and can change without notice. Renew from expires_in, and don't treat every 401 as an expired token.
  • A valid token doesn't decide what data comes back. Service account permissions, Developer Console permission sets, or WFM function access profiles do.
  • UKG webhooks are near real-time, retained for 14 days, and free up to 10,000 events a month. UKG itself recommends a polling backstop for critical data.

UKG Pro API authentication, architecture, and data access:

UKG Pro is a product name, not a single API. Ask its developer hub for "the" authentication flow and you'll find several: Basic auth with API keys for the core HCM REST APIs, a login token for the SOAP services, OAuth tokens for Recruiting and Onboarding, and OAuth 2.0 client credentials for Workforce Management and the newer Pro Platform APIs.

They aren't random. They're two generations of UKG auth running side by side, and the real integration problem is knowing which generation each endpoint, and each customer's tenant, is on.

This guide maps the auth model for each UKG Pro API family, explains why UKG wants client credentials for automation, sorts out the token lifetimes, shows what actually governs data access once a token is valid, and covers how to design the layer that sits on top of all of it.

The auth model for each UKG Pro API family

API familyLegacy authModern authWhat decides the data you get
Core HCM REST (personnel, payroll, configuration)HTTP Basic with a web service account, plus the US-Customer-Api-Key headerCheck each endpoint's reference. Newer Pro Platform APIs take Developer Console client credentials.The service account's web service permissions in Service Account Administration
HCM SOAP servicesLogin Service token from a service account or web user, plus the Customer and User API keysNone. SOAP stays on the login token.The same service account permissions
Recruiting and Onboarding RESTOAuth 2.0 authorization token with identity scopesSameThe identity scopes on the token
Pro Workforce Management (WFM)ROPC with a named WFM user (the default for existing clients), or authorization codeOAuth 2.0 client credentialsThe function access profile (FAP) on the client, or the named user's own access for ROPC
Pro Platform (Developer Console)Not applicableOAuth 2.0 client credentials, sent with a global-tenant-id headerThe permission set attached to the client in the Developer Console
UKG Webhooks (inbound to you)Optional HMAC secret, 24+ charactersSameThe events you subscribe to
Credentials are tenant specific. Non-production credentials are rejected by production tenants.

The legacy column is where most existing integrations live. The core HCM REST APIs authenticate with HTTP Basic using a web service account, plus your tenant's Customer API Key in a header:

Core HCM REST · Basic auth plus Customer API Key
curl "https://{service_host}/personnel/v1/person-details" \
  -H "Authorization: Basic {base64(service_account_username:password)}" \
  -H "US-Customer-Api-Key: {customer_api_key}"

# {service_host} is tenant specific, e.g. service4.ultipro.com.
# The service account needs the View role on the Personnel Integration web service.

The modern column is UKG's direction. In the Developer Console, you create a client, attach a permission set, and exchange its ID and secret for a bearer token. Pro Platform APIs take that token plus a global-tenant-id header. Pro WFM offers the same client-credentials flow, with each client tied to a function access profile. Recruiting and Onboarding use their own OAuth tokens with identity scopes.

Client credentials · WFM token request, and the Pro Platform variant
# UKG Pro WFM (UKG Authentication), from UKG's WFM docs:
curl -X POST "https://welcome-us.ukg.net/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "{client_id}",
    "client_secret": "{client_secret}",
    "audience": "https://wfm.ukg.net/api",
    "grant_type": "client_credentials",
    "organization": "{organization}"
  }'

# Pro Platform: take the Generate Token URL, audience and organization
# from the Developer Console, request a token the same way, then send:
#   Authorization: Bearer {access_token}
#   global-tenant-id: {organization}

# Always schedule renewal from the response's "expires_in", never a hardcoded number.

HCM SOAP is the odd one out. It predates the REST APIs, still speaks XML over SOAP, and authenticates through a Login Service token, so it doesn't map onto either OAuth pattern. Whatever you build against, remember that credentials are tenant specific. A client created in one UKG tenant won't work in another, and non-production credentials are rejected by production.

Why UKG wants client credentials for automation

RFC 6749, the OAuth 2.0 framework, defines client credentials as a grant for a client acting on its own behalf, with no human logging in behind it. ROPC, the password grant, models a specific user's login instead.

UKG is blunt about which to use. Its authentication guidance marks client credentials as required for system-to-system access, and says to fall back to ROPC only for endpoints client credentials can't reach. The reason is practical. UKG's authentication service protects user accounts, so a nightly job logging in as a named user can trip that protection. The job gets 429 responses, then an account lockout, and every other job using that account stops with it.

UKG's checklist for going live is short and worth following:

  • Create separate client credentials per integration, and per data center if you run in more than one.
  • Centralize tokens in one service or shared cache, and reuse them across workers instead of generating them in parallel.
  • Handle 429 responses with exponential backoff, and honor Retry-After.
  • Keep named-user credentials out of automated jobs.

How long UKG tokens last, and why the number shouldn't matter

Search UKG's developer hub for token lifetimes and you'll find several numbers. They come from different products:

  • UKG Pro WFM: access tokens expire after 30 minutes and refresh tokens after 8 hours, per UKG Authentication.
  • UKG Talk: refresh tokens expire after 7 days, per its authentication page.
  • UKG HR Service Delivery, a separate product, shows an expires_in of 8,640,000 seconds (100 days) in its OAuth example.

None of them is a UKG Pro constant, and UKG says so directly: the limits are subject to change without notice, and you should renew based on the expires_in value in each token response rather than a fixed schedule.

UKG adds one more warning worth building in from the start. Don't assume a 401 or 403 means the token expired. The same status can mean a permission or configuration problem, and a client that refreshes on every 401 will loop forever on a credential that was simply never granted the data.

A valid token doesn't mean you can read the data

A valid, unexpired token gets your request past the door. It doesn't decide what's on the other side. That's set on the credential itself, and where it's set depends on which generation you're on:

CredentialWhere its data access is set
Web service account (Basic auth, SOAP login)Service Account Administration, per web service. For example, Personnel Integration needs the View role to read people.
Pro HCM or Pro Platform client credentialsThe permission set attached to the client in the Developer Console
WFM client credentialsThe function access profile (FAP) assigned to the client
WFM ROPCWhatever the named user can see

This is easy to miss because the symptom looks like a bug in your own code. A service account without the right web service permission gets refused on that service, even with a perfectly valid key. A client built and tested against one tenant's permission set carries none of those grants into another tenant.

So the design question isn't only which auth model to use. It's which permissions the credential needs before you ever call the endpoint, and who at the customer grants them.

Designing the integration layer on top

Several auth models don't have to mean several independent integrations. In practice they mean one client per auth generation, each holding its own credentials and renewal logic, feeding one canonical data model that normalizes UKG's field names and record shapes into something the rest of your product can use without knowing where a field came from.

Validation, retries and logging belong at that normalization layer, because that's the one place a broken mapping is visible before it reaches a customer's record. Token handling belongs in one shared service, which is exactly what UKG's own guidance asks for.

Verifying a webhook came from UKG

UKG Webhooks lets you set an HMAC secret of at least 24 characters on each subscription. It's optional. Set one anyway, because without it your endpoint accepts whatever anyone posts to its URL.

Verification follows the HMAC pattern, but with a detail that trips people up. UKG points integrators to the Svix verification scheme, which signs the message ID, timestamp and raw body together. A receiver that hashes only the payload will reject every genuine event:

Python · Verify a UKG webhook (Svix-style signature)
import base64, hashlib, hmac, time

def verify_ukg_webhook(headers, raw_body: bytes, secret: str, tolerance_s: int = 300) -> bool:
    # UKG follows the Svix verification scheme with the "svix" prefix renamed
    # to "webhooks". Confirm the exact header names on your first test event.
    msg_id = headers["webhooks-id"]
    timestamp = headers["webhooks-timestamp"]
    signatures = headers["webhooks-signature"]   # e.g. "v1,<base64> v1,<base64>"

    # Reject stale or future-dated messages to block replays.
    if abs(time.time() - int(timestamp)) > tolerance_s:
        return False

    # Svix-format secrets start with "whsec_" and are base64 encoded.
    # If yours has no prefix, use it as entered and confirm with a test event.
    key = (base64.b64decode(secret[len("whsec_"):])
           if secret.startswith("whsec_") else secret.encode())

    # Sign the message ID, timestamp AND raw body, not the body alone.
    signed = f"{msg_id}.{timestamp}.".encode() + raw_body
    expected = base64.b64encode(hmac.new(key, signed, hashlib.sha256).digest()).decode()

    for sig in signatures.split(" "):
        version, _, value = sig.partition(",")
        if version == "v1" and hmac.compare_digest(value, expected):
            return True
    return False

For more on why this matters, see how HMAC secures your webhooks.

Keeping data current: polling or webhooks

There are two ways to find out a UKG Pro record changed: ask on a schedule, or wait for UKG to tell you. Polling is simple and predictable, but data is only as current as the last poll. Webhooks push changes in near real time, with limits you should design around:

  • Retention: UKG keeps webhook events for 14 days.
  • Volume: the free tier stops at 10,000 notifications per calendar month, which a large tenant can burn through during open enrollment. More requires Webhooks Premium.
  • Delivery: events can be missed, for example when database triggers are disabled. For business-critical integrations, UKG itself recommends a secondary polling sync or nightly report.

In other words, webhooks tell you something changed sooner. Polling is what makes sure you never miss it. Most production UKG integrations need both.

Where Bindbee fits

Bindbee is a unified API for 67+ HRIS, payroll, ATS and benefits systems, UKG Pro among them. Its UKG Pro connector uses the core HCM path described above. Your customer's UKG admin creates a service account with the web service permissions you need and enters it, with the Customer API Key, through a Magic Link, following Bindbee's UKG Pro setup guide.

From there Bindbee owns the rest:

  • Calls, paging and retries against UKG's services.
  • Normalizing UKG records into the same models as every other connected system.
  • Custom Fields, for UKG fields the unified model doesn't carry yet, mapped with a JMESPath expression instead of waiting on a schema change.
  • Write-back through the same API.

Syncs run every 24 hours by default, adjustable per connection. Bindbee's webhooks fire when a sync finishes or finds created or updated records, so your product knows the moment fresh data is ready.

For a layer that touches employee and benefits data, compliance matters as much as API coverage. Bindbee is SOC 2 Type II and ISO 27001 certified, HIPAA and GDPR compliant, and offers a standard BAA template, negotiated for enterprise agreements.

Also connecting Workday? Read our Workday API architecture guide.

FAQ

How do I get UKG Pro API credentials?

For the core HCM APIs, a UKG Pro administrator creates a web service account in Service Account Administration, grants it permissions per web service, and copies the Customer API Key shown on that page. For client-credentials access, the client ID and secret are created in the Developer Console (System Configuration > Security > Developer Console in Pro HCM, or Administration > Developer Console in Pro WFM).

Does UKG Pro support OAuth 2.0 client credentials?

Yes, for UKG Pro WFM and for Pro Platform APIs, through clients created in the Developer Console or WFM Client Management. UKG requires client credentials for system-to-system integrations and says to use ROPC only for endpoints client credentials can't reach. Core HCM REST endpoints documented with Basic authentication still use a web service account.

Why does a valid UKG token return a 401, a 403, or no data?

A token only proves the request is accepted. What it can read is set by the service account's web service permissions, the Developer Console permission set, or the WFM function access profile. UKG also warns that a 401 or 403 doesn't necessarily mean the token expired, so check permissions and configuration before refreshing.

How long does a UKG access token last?

It depends on the product and flow. UKG's WFM authentication docs list 30-minute access tokens and 8-hour refresh tokens, and state both can change without notice. Always read expires_in from the token response instead of hardcoding a lifetime.

Do UKG webhooks guarantee delivery?

No. UKG describes webhooks as near real-time, retains events for 14 days, and notes events can be missed, for example when database triggers are disabled. For business-critical integrations UKG recommends a secondary polling sync or nightly report.

Kunal Tyagi
CTO
Bindbee
VIEW AUTHOR
BLOG_

Related blogs