---
title: "Create OAuth configuration"
method: POST
path: "/oauth/{connectorType}"
tags: ["OAuth Configuration"]
---

# Create OAuth configuration

`POST /oauth/{connectorType}`

## Request

- Base URL: `https://app.pipeshub.com/api/v1`
- URL: `https://app.pipeshub.com/api/v1/oauth/{connectorType}`
- Auth: one of:
  - HTTP bearer
  - OAuth 2
    - Authorization code: `/api/v1/oauth2/authorize`
    - Client credentials
    - Token URL: `/api/v1/oauth2/token` scopes: `connector:write`

Create a new OAuth configuration for a connector type.<br><br>
<b>Admin Only:</b><br>
Only admins can create OAuth configurations. These provide the
OAuth credentials needed for users to authenticate connectors.<br><br>
<b>Use Case:</b><br>
Before users can create Google Drive connectors with OAuth,
an admin must create an OAuth configuration with the Google
OAuth client ID and secret.<br><br>
The response carries the credential-free view of the new configuration; the
credentials are never echoed back. Success is reported as `200`, not `201`.<br><br>
<b>The connector type is not checked.</b> `connectorType` is not compared with the OAuth
registry, so a misspelled or wrongly-cased name (`confluence` for `Confluence`) does not
fail: the configuration is stored under that name with the default icon and an empty
group, description and category list. It is then returned by
`GET /oauth/{connectorType}` for that same name but never by `GET /oauth`, which only
walks the registered types.<br><br>
Body fields other than `oauthInstanceName`, `config` and `baseUrl` are ignored.

## Path parameters

- `connectorType` string, required

## Request body

- CreateOAuthConfigRequest: Request to create OAuth configuration (admin only). Stores credentials that users select when setting up connectors.
  - `oauthInstanceName` string, required: Display name for this OAuth configuration (e.g., 'Production Google OAuth'). Must be unique for the connector type within the organization. Leading and trailing whitespace is removed before validation, so a name of only whitespace is refused as empty.
  - `config` object, required: OAuth application credentials, keyed by the `name` of each entry in the connector type's `authFields` (see `GET /oauth/registry/{connectorType}`), so the keys differ from one connector type to the next. Must not be empty; neither the keys nor their values are validated when the configuration is created, so a value of another type (a number, `null`, a nested object, an array of other items) is stored as sent, also for `clientId` and `clientSecret`.
    - `clientId` string: OAuth client ID from your OAuth application
    - `clientSecret` string: OAuth client secret; never in the create response, and returned by GET only to admins (masked when HIDE_SECRET_CONFIG is on)
    - `tenantId` string: Azure tenant ID (required only for Microsoft connectors)
  - `baseUrl` string: PipesHub's public origin, prefixed to the connector's redirect path to build the stored redirectUri. When omitted or empty, the frontend public endpoint is used. The value is not checked to be a URL: whatever text is sent is used as the prefix. Not the provider's URL; a self-hosted provider's address goes in config.

## Response `200`

OAuth configuration created

- object
  - `success` boolean, required
  - `oauthConfig` OAuthConfig, required: A saved OAuth app for a connector type. Admins also get `config` (secrets masked when HIDE_SECRET_CONFIG is on) and, in lists, the provider endpoints.
    - `_id` string, uuid: OAuth app ID: the `oauthConfigId` to link a connector to
    - `oauthInstanceName` string
    - `connectorType` string
    - `iconPath` string: Icon of the connector type, copied from the OAuth registry when the configuration was created
    - `appGroup` string: Application group of the connector type (empty when the type is not in the OAuth registry)
    - `appDescription` string: Description of the connector type's OAuth application
    - `appCategories` string[]: Categories of the connector type
    - `config` object: OAuth app credentials; keys follow the connector type's OAuth fields
      - `clientId` string
      - `clientSecret` string
    - `userId` string
    - `updatedBy` string
    - `createdAtTimestamp` integer: Epoch milliseconds
    - `updatedAtTimestamp` integer: Epoch milliseconds
    - `authorizeUrl` string
    - `tokenUrl` string
    - `redirectUri` string
    - `scopes` object: Provider scopes requested per use
  - `message` string, required

## Other responses

- `400`: Invalid request: `oauthInstanceName` or `config` is missing or empty. Also returned, before authentication, when a query value, or any string in a JSON or form-encoded body, looks like markup to the app-wide XSS filter: an HTML tag, a script tag, `<iframe`, `<object`, `<embed` or `<svg` tag, a word starting with `on` followed by `=` (meant for inline event handlers such as `onerror=`, it also catches plain text such as `one=1`), a `javascript:` or `data:text/html` URL, an encoded script tag (`&lt;script`, `%3cscript`), or any string longer than 100,000 characters (`HTTP_BAD_REQUEST`, "HTML tags, scripts, and XSS content are not allowed in ...", naming the field or query parameter; a string over 100,000 characters is refused as too long instead). A JSON body that does not parse is refused the same way, also before authentication (`HTTP_BAD_REQUEST`, "The request body is not valid JSON.").
- `401`: Missing or invalid credentials
- `403`: Forbidden — one of: - the OAuth token lacks the `connector:write` scope - the token lacks `connector:write`, or the caller is not an admin
- `409`: Another of the org's OAuth apps for this connector type already has this `oauthInstanceName`
- `500`: Internal error, for example when the JSON body is not an object A JSON body larger than 10 MB, or a form-encoded body larger than 100 KB or with more than 1000 fields, is answered `413` by the app-wide body parsers instead, also before authentication.

## Changes

- **2026-10-28** `dbb5e203b445`: 1 breaking, 2 warning, 3 info
  - added the pattern `\S` to the request property `oauthInstanceName`
  - removed the optional property `oauthConfig/createdBy` from the response with the `200` status
  - removed the optional property `oauthConfig/orgId` from the response with the `200` status
  - the request property `config/clientId` became optional
  - …2 more
- **2026-10-15** `a44792e4f0e6`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/changes/oauth/:connectorType/post.md)

---

[API](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api.md) - [All operations](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/llms.txt) - [OpenAPI document](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/revisions/dbb5e203b445?raw)
