---
title: "OAuth callback handler"
method: GET
path: "/connectors/oauth/callback"
tags: ["Connector OAuth"]
---

# OAuth callback handler

`GET /connectors/oauth/callback`

## Request

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

Finish the OAuth sign-in: exchange the provider's <code>code</code> for tokens and store
them. Call it with the <code>code</code> and <code>state</code> the provider sent to the redirect URI,
as the connector's creator or an admin.<br><br>
<b>Result:</b><br>
Always JSON. <code>success</code> is true when the connector is signed in; otherwise
<code>error</code> and <code>errorMessage</code> say why. Provider tokens are never returned.

## Query parameters

- `code` string, required
- `state` string, required
- `error` string
- `baseUrl` string

## Response `200`

Result of exchanging the code. `success` is false when the provider refused it.

- object
  - `success` boolean, required: Whether tokens were stored and the connector is authenticated
  - `redirectUrl` string: Where the web app would send the user next
  - `error` string: Only when `success` is `false`. The provider's own code when it was passed in `error`, otherwise one of `invalid_state`, `instance_not_found`, `config_not_found`, `oauth_config_fetch_error`, `invalid_token` or `server_error`.
  - `errorMessage` string: Only when `error` is `server_error`. A readable reason for the failed token exchange.

## Other responses

- `400`: Invalid request: a parameter or the body failed validation 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`: The token lacks a required scope, or the caller may not use this connector
- `500`: Internal server error. 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`: 2 breaking, 1 info
  - added the pattern `\S` to the `query` request parameter `code`
  - added the pattern `\S` to the `query` request parameter `state`
  - added the non-success response with the status `500`
- **2026-10-15** `a44792e4f0e6`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/pipeshub-ai/apis/pipeshub-api/changes/connectors/oauth/callback/get.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)
