Skip to main content
Many connector types authenticate via OAuth 2.0 rather than a plain username/password or API key. Setting one up requires walking the end user through a browser-based authorization step before the connector can be created.

Which connector types use OAuth

These types require the authorization flow described below: GITHUB, GITHUB2, BITBUCKET, BOX, ONEDRIVE, SHAREPOINT, GOOGLE, GOOGLE_DRIVE2, SALESFORCE, VERBIS, HUBSPOT, ZENDESK, CONTENTFUL, CONTENTFULENTRYLEVEL, CONTENTFUL2.
Some similarly-named types are not OAuth-based, and calling the authorization endpoint for them will fail: GITLAB and BITBUCKETSERVER use a plain host+token (personal access token), MARKETO uses an API key/secret pair, and OPTIMIZELY/TRIDION use OIDC client-credentials with no user redirect at all. PHRASE (the connector to Phrase Strings) also isn’t OAuth, despite having a code-shaped field — see the note at the end of this page.

The authorization flow

1. Get a one-time state token

This returns a one-time state token that correlates your authorization attempt with the eventual callback.

2. Get the authorization page URL

  • {type} must be the exact same ConnectorType enum value you’ll use to create the connector — not an abbreviation, and not a differently-cased variant. This matters more than it sounds: for example, Google Drive’s correct type is GOOGLE_DRIVE2. GOOGLE_DRIVE doesn’t exist as a type, and GOOGLE is a different, separate connector type — calling this endpoint with GOOGLE returns 200 successfully, but authorizes against the wrong provider configuration, and will break connector creation later. A 400 response here almost always means the type value is wrong, not that a parameter is missing.
  • hostPrefix should be the bare TMS hostname (host only, no scheme or path — e.g. qa.memsource.com).
The returned url field is a template, not a ready-to-use link. It contains literal placeholder text — {state} and {redirectUri} — that you must substitute yourself before sending it anywhere. The backend does not fill these in.
Substitute:
  • {state} → the token from step 1.
  • {redirectUri}<TMS host>/web/connector/receiveConnectorAuthCode (this exact path is correct for every provider — don’t vary it, and don’t guess an alternative like /tms/...).
If the third-party provider rejects the resulting link with something like “redirect_uri is not associated with this application,” that means this fixed path doesn’t match what’s registered for that specific OAuth app — that’s a configuration question for whoever manages the app’s registered callback URLs, not something to work around by guessing a different path. Only send the user a fully substituted URL — never one still containing literal {state} or {redirectUri} text, since the provider will reject it outright.

3. Let the user authorize, then poll for the code

Once the user completes the provider’s sign-in and consent screen, their browser is redirected to the callback URL above with the real authorization code attached — but that callback page auto-submits the code server-side and the URL reverts within seconds, too fast to copy by hand. Instead, poll for it:
Despite the path parameter’s name, pass the state token from step 1 here, not a code you don’t have yet — the parameter is misleadingly named. Poll every few seconds until the response contains a populated code (not null). If the user reports landing on the callback page with no code and no visible error, this is usually a stale or reused state token — restart from step 1 with a fresh one.

4. Create the connector

Create the connector using the code you polled for, following the type-specific fields documented in the API reference.

GitHub Apps (GITHUB2) need one extra step

GITHUB2 uses GitHub’s newer “GitHub App” model rather than a classic OAuth App, which has two extra requirements beyond the flow above: The Phrase GitHub App must be installed on the user’s GitHub account or organization — OAuth sign-in alone does not install it. Direct users to install it here, ideally alongside the authorization link rather than only after a failure:
An extra API call is required before creating the connector, since its payload needs login and tempLocalToken fields that the standard code exchange doesn’t provide:
This returns { "localToken": "...", "logins": [...] }. If logins has more than one entry, ask the user which GitHub org/account to connect. Then create the connector with:
Don’t pass code/redirectUri directly to the create call for GITHUB2 — that request shape is for classic GITHUB connectors only.

PHRASE connectors are the exception

The PHRASE connector type (which connects TMS to Phrase Strings, not another TMS instance or a third party) has a code-shaped field but is not part of this OAuth flow — it has no third-party OAuth provider registered, and calling connectorAuthPage for it returns an empty url by design. Its authorization is instead resolved server-side from your own authenticated identity. Attempt creation directly with the connector’s base fields plus its Strings-specific fields (phraseTmsOrganizationId/phraseTmsOrganizationName).