# How to connect to SAP SuccessFactors

SAP SuccessFactors does not use a one-click authorization screen. Instead, an administrator
registers an **OAuth Client Application** with an X.509 certificate inside your own
SuccessFactors instance, and then enters five values in Vault. Apideck uses those values to sign
a SAML assertion and mint access tokens on your behalf (OAuth2 SAML2-Bearer Assertion), so once
the connection is saved the only thing left to renew by hand is the X.509 certificate before it
expires.

## Before you start

You will need:

- **An administrator account in the SuccessFactors instance you want to connect**, with
  Admin Center access sufficient to reach and use the **Manage OAuth2 Client Applications**
  screen. If you cannot open that screen, your SuccessFactors administrator can grant the
  necessary permissions via **Admin Center > Manage Permission Roles**.
- **A decision about which SuccessFactors user the connection will run as**, and that user's
  SuccessFactors `userId` *before* you register the client; you enter it during registration
  (step 2) and again in Vault (step 4). Points worth weighing:
  - Every API call runs with that user's SuccessFactors permissions, so the user needs OData read
    access to the entities you plan to sync, and write access if your integration creates or
    updates records.
  - A dedicated API/service user is usually a better choice than a named individual's account,
    which may be deactivated when that person leaves.
  - The value you need is the SuccessFactors-internal **userId**, not a username or email address.
    **Admin Center > Integration Center** is the authoritative place to look it up (step 3).
- **OData API access enabled on that instance**, for the module you intend to sync: Employee
  Central for HRIS data, Recruiting for ATS data.
- **A decision about which instance you are connecting.** Each SuccessFactors instance, test and
  production, has its own API server, Company ID, and OAuth client. Credentials are *not*
  interchangeable between them, so plan on running this procedure once per instance.
- **A tool to generate an X.509 key pair** (for example OpenSSL), or the certificate generator
  built into the SuccessFactors API Center. See step 1.

## 1. Generate an X.509 key pair

Apideck signs the SAML assertion with the **private key**, so you must end up holding the private
key yourself: it is one of the five values you paste into Vault.

**Recommended:** generate the key pair with your own tooling, then upload only the public
certificate to SuccessFactors in step 2. Apideck recommends this route because the private key
then never transits the SuccessFactors UI.

**Alternative:** generate the certificate inside the registration screen in step 2 (**Generate
X.509 Certificate**) and download the private key when prompted. This is a supported route and it
works, but we suggest avoiding it where you can: downloading the private key from the API Center
widens its exposure. If you do take this route, download the private key at generation time: you
cannot retrieve it later.

Either way, keep the private key `.pem` file to hand, and note the certificate's expiry date: when
the certificate lapses, token requests start failing and the connection stops returning data, so
plan to re-register with a fresh certificate before that happens.

Reference: [Creating an X.509 Certificate in SAP SuccessFactors](https://help.sap.com/docs/successfactors-platform/sap-successfactors-api-reference-guide-odata-v4/creating-x-509-certificate-in-sap-successfactors).

## 2. Register a Client Application in SuccessFactors

Everything in this step happens on one form: the certificate and the user binding are both fields
on the registration screen, not separate screens to visit afterwards.

1. Sign in to the SuccessFactors instance you are connecting as an administrator.

2. Navigate to **Admin Center > API Center > OAuth Configuration for OData**. You can also reach
   the same tool by searching for **Manage OAuth2 Client Applications** in Action Search.

3. Choose **Register Client Application**.

4. On the "Register an application" page, fill in:
   - **Company**: the name of your company.
   - **Application Name**: a unique name for the OAuth client. Something identifiable such as
     `Apideck` makes it easier to find and revoke later.
   - **Application URL**: a URL describing the client application. This field is only used for
     3-legged OAuth, which is not part of this flow, so any valid URL you control is fine.
   - **Bind to Users** (also labelled *Bind to Technical User* in some releases): select this
     checkbox and enter the **userId** of the user the connection will run as, the one you decided
     on in "Before you start". This must be the SuccessFactors-internal **userId**, not a username
     or email address. Look it up in **Admin Center > Integration Center** (step 3).
   - **X.509 Certificate**: paste the **public certificate** from step 1, including the
     `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` lines. Alternatively, choose
     **Generate X.509 Certificate** here and download the private key.

5. Choose **Register** to save.

6. Find the new entry in the registered application list and choose **View** to reveal its
   **API Key**. That value is what Vault calls the Client ID.

Why the binding matters: if no user is bound to the client application, interactive business users
can still request tokens, but a technical/service user cannot, and a dedicated API/service user
is exactly what this guide recommends running the connection as. Binding that user during
registration is what makes its token requests succeed. Keep the bound `userId` and the value you
will enter in **Username** (step 4) identical, character for character.

References: [Registering Your OAuth2 Client Application](https://help.sap.com/docs/successfactors-platform/sap-successfactors-api-reference-guide-odata-v2/registering-your-oauth2-client-application)
and SAP KBA [2850646: How to register for OAuth 2.0 authentication](https://userapps.support.sap.com/sap/support/knowledge/en/2850646).

## 3. Collect the five values Vault needs

All five come from the same instance you just registered the client in.

| Vault field | What to enter | Where to find it |
|---|---|---|
| **API server** | Your instance's API data-center hostname, e.g. `apisalesdemo8.successfactors.com` | [List of SAP SuccessFactors API Servers](https://help.sap.com/docs/SAP_SUCCESSFACTORS_PLATFORM/2abbb39286994389bb0f1f4418773a7c/af2b8d5437494b12be88fe374eba75b6.html): match the row for your data center |
| **Company ID** | The instance's company identifier | In SuccessFactors, click your profile image (upper right) > **Show version information**, and read the **Company ID** value |
| **Username** | The `userId` of the user the connection runs as, the same value you bound to the client application in step 2 | **Admin Center > Integration Center** resolves a user's `userId`, and is the authoritative route for this value (SAP KBA [3156552](https://userapps.support.sap.com/sap/support/knowledge/en/3156552)). The value in parentheses beside your name in the profile-image panel is the *username*: it matches the `userId` on many tenants but is not guaranteed to, so confirm it in Integration Center if authorization fails |
| **Client ID** | The **API Key** from the Client Application you registered in step 2 | **Admin Center > API Center > OAuth Configuration for OData**, then **View** on your application |
| **Client secret** | The full contents of the private key `.pem` file from step 1, including the `-----BEGIN`/`-----END` lines | Your own key file |

Two things worth getting right here:

- **Username must match the bound `userId` from step 2.** It also determines what Apideck can read:
  every API call runs with that user's SuccessFactors permissions (see "Before you start").
- **API server is a hostname, not a URL.** Vault adds the `https://` prefix and the trailing slash
  for you, so enter `apisalesdemo8.successfactors.com` rather than
  `https://apisalesdemo8.successfactors.com/`.

## 4. Enter the credentials in Vault

1. Open the SAP SuccessFactors connector in Vault and paste in the five values from step 3.
2. Click **Save**.
3. Click **Authorize**. Apideck signs a SAML assertion with your private key and exchanges it for
   an access token against your instance. A successful authorization means the credentials and the
   user binding are working.

Your SAP SuccessFactors account is now connected.

## Notes

- **One connection serves both verticals.** The same credentials back HRIS (Employee Central) and
  ATS (Recruiting) data: you do not register separate clients per Unified API. What you actually
  get back is bounded by which modules are enabled on the instance and by the permissions of the
  user in the **Username** field.
- **Token handling is automatic.** Each time Apideck authenticates or refreshes the connection, it
  signs a fresh short-lived SAML assertion (valid 10 minutes) and asks SuccessFactors for a
  genuinely new access token rather than accepting one SuccessFactors may still be holding, so the
  token in use is always newly issued at that point. That token is then reused for up to 24 hours
  before Apideck requests the next one. There is no refresh token to store and nothing to rotate on
  your side apart from the X.509 certificate when it approaches expiry.
- **Revoking access** is done from your side: delete the registered Client Application in
  **Admin Center > API Center > OAuth Configuration for OData**. That immediately stops Apideck
  from obtaining any *new* token. SuccessFactors may not invalidate a token Apideck already holds,
  so assume the connection can keep working for up to 24 hours before it fails on its next token
  request. If you need access to stop sooner than that, also delete the connection in Vault: that
  removes the stored credentials and the token along with them.
- **Repeat per instance.** Connecting your test instance after your production instance (or the
  reverse) means a second Client Application, a second certificate, and a second Vault connection
  with that instance's own API server and Company ID.

## Troubleshooting

**"Unable to generate token. User is not bound to the client application."** This is SAP's own
error text, and it means exactly what it says: the user in **Username** is a technical/service user
that was not bound to the OAuth client application. Reopen the registration in **Admin Center >
API Center > OAuth Configuration for OData**, select **Bind to Users**, enter that user's `userId`,
and save (step 2). Note this error only appears for technical/service users: an unbound
*interactive* business user can still obtain tokens, which is why the same client can look fine
when tested under an admin's own account and fail for the service user the connection runs as.

**"This User ID is not a Technical User ID."** On releases where the binding field is labelled
**Bind to Technical User**, it validates that the ID you enter belongs to a technical user, so
entering a regular business or named-individual user's ID is rejected with this error (SAP KBA
[2895460](https://userapps.support.sap.com/sap/support/knowledge/en/2895460)). Either bind a
dedicated technical/API user, the option this guide recommends, or, if the connection must run
as a named individual, leave the binding off entirely: an unbound interactive business user can
still obtain tokens.

**Authorization fails with an invalid grant or 401 error.** Work through the five values in order:

- **Client ID** must be the generated *API Key*, not the application name you chose.
- **Client secret** must be the *private* key, complete with its `-----BEGIN`/`-----END` lines and
  line breaks intact, not the public certificate, and not a truncated copy/paste.
- **Username** must be the SuccessFactors-internal `userId`, not an email address, a display name,
  or the username in the profile-image panel unless Integration Center confirms the two match, and
  must equal the `userId` bound to the client application in step 2 exactly.
- **Company ID** and **API server** must both belong to the *same* instance in which the OAuth
  client was registered. Mixing a test Company ID with a production API server is the most common
  cause of this failure.

**Authorization succeeds but requests return no data.** The user in **Username** most likely lacks
OData permissions for that entity. Grant read access for the entities you are syncing and retry.

**Requests fail for an entity that exists in your instance.** Confirm the relevant module has
OData API access enabled: Employee Central for HRIS entities, Recruiting for ATS entities.

**The connection worked and then stopped.** Check whether the X.509 certificate on the registered
Client Application has expired, or whether the user in **Username** has been deactivated. Both
break token minting without any change on the Apideck side.

Still stuck? Contact [Apideck Support](https://help.apideck.com/en/articles/7774658) with the
Company ID and API server you used (never the private key) and we can check what the authorization
attempt returned.
