> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://ocient.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://ocient.ferndocs.com/_mcp/server.

# Begin SSO authentication flow

POST /v1/sso_authentication
Content-Type: application/json

Initiates the OpenID Connect authentication flow by redirecting to
the authorization server.

This endpoint begins the standard OpenID Connect authentication flow:

1. The client calls this endpoint with a callback path
2. The server responds with a redirect to the identity provider
3. The user authenticates with the identity provider
4. The identity provider redirects back to the callback endpoint
5. The client can then exchange the authorization code for an access token

### Usage Example

```javascript
// Browser-based flow
fetch('/v1/sso_authentication', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    database: 'retail_analytics',
    sso_callback_path: '/auth/callback'
  })
})
.then(response => {
  // The browser will be redirected to the SSO provider
  window.location.href = response.url;
});
```

Reference: https://ocient.ferndocs.com/api-reference/sso-integration/startsso

## Request

### Body (application/json)

This endpoint expects a SSOAuthenticationRequest.

- `database` (string, optional) — Target database name (defaults to system if not specified)
- `sso_callback_path` (string, optional) — Local path to redirect to after successful authentication. This path should be registered with your OpenID provider as a valid redirect URI.
- `do_redirect` (boolean, optional, default: true) — Whether to issue the redirect to the authentication server immediately. - If true (default), the API will respond with a 302 redirect to the OpenID provider - If false, the API will return the URL in the response body, allowing the client to handle the redirect manually If SSO is not configured for the database, an error will occur if do_redirect is true, or an empty redirect will be returned if do_redirect is false.

## Errors

### 401 Unauthorized Error

Unauthorized

- `status` (Status, required)

### 404 Not Found Error

Object not found

- `status` (Status, required)

## Types

### Status

- `reason` (string, required) — Human-readable description of the operation result
- `sql_state` (string, required) — SQL state code (see Error Handling section for common codes)
- `vendor_code` (integer, required) — Vendor-specific error code

## Examples

**Request**

```json
{
  "database": "retail_analytics",
  "sso_callback_path": "/auth/callback",
  "do_redirect": true
}
```

**SDK Code**

```python
import requests

url = "https://v1/sso_authentication"

payload = {
    "database": "retail_analytics",
    "sso_callback_path": "/auth/callback",
    "do_redirect": True
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://v1/sso_authentication';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{"database":"retail_analytics","sso_callback_path":"/auth/callback","do_redirect":true}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://v1/sso_authentication"

	payload := strings.NewReader("{\n  \"database\": \"retail_analytics\",\n  \"sso_callback_path\": \"/auth/callback\",\n  \"do_redirect\": true\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://v1/sso_authentication")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"database\": \"retail_analytics\",\n  \"sso_callback_path\": \"/auth/callback\",\n  \"do_redirect\": true\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://v1/sso_authentication")
  .header("Content-Type", "application/json")
  .body("{\n  \"database\": \"retail_analytics\",\n  \"sso_callback_path\": \"/auth/callback\",\n  \"do_redirect\": true\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://v1/sso_authentication', [
  'body' => '{
  "database": "retail_analytics",
  "sso_callback_path": "/auth/callback",
  "do_redirect": true
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://v1/sso_authentication");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"database\": \"retail_analytics\",\n  \"sso_callback_path\": \"/auth/callback\",\n  \"do_redirect\": true\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = [
  "database": "retail_analytics",
  "sso_callback_path": "/auth/callback",
  "do_redirect": true
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://v1/sso_authentication")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```